lookup_on_load
到Agent_onload⽅法,再回到create_vm_init_agents 。接下来的⼯作就是调⽤Agent_OnLoad⽅法,进⾏agent的初始化。
2、执⾏Agent_OnLoad,创建Instrument JPLISAgent, 并且初始化JPLISAgent过程中注册了event 的处理钩⼦。
Agent_OnLoad是⼀个外部的c函数,看⼀下。(定义位置: jdk7u/jdk/src/share/instrument/InvocationAdapter.c)
在⽅法Agent_OnLoad中创建⼀个新的 JPLISAgent(Java Programming Language Instrumentation Services Agent),初始化了类和包⾥的配置⽂件,并且同时从Vm环境中获取了 jvmtiEnv 的环境。
/*
*  This will be called once for every -javaagent on the command line.
*  Each call to Agent_OnLoad will create its own agent and agent data.
*
*  The argument tail string provided to Agent_OnLoad will be of form
*  <jarfile>[=<options>]. The tail string is split into the jarfile and
*  options components. The jarfile manifest is parsed and the value of the
*  Premain-Class attribute will become the agent's premain class. The jar
*  file is then added to the system class path, and if the Boot-Class-Path
*  attribute is present then all relative URLs in the value are processed
*  to create boot class path segments to append to the boot class path.
*/
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *tail, void * reserved) {
JPLISInitializationError initerror  = JPLIS_INIT_ERROR_NONE;
jint                    result    = JNI_OK;
JPLISAgent *            agent      = NULL;error parse new
// 这个函数的核⼼:创建⼀个新的JPLISAgent对象
initerror = createNewJPLISAgent(vm, &agent);
if ( initerror == JPLIS_INIT_ERROR_NONE ) {
int            oldLen, newLen;
char *          jarfile;
char *          options;
jarAttribute*  attributes;
char *          premainClass;
char *          agentClass;
char *          bootClassPath;
/*
* Parse <jarfile>[=options] into jarfile and options
*/
if (parseArgumentTail(tail, &jarfile, &options) != 0) {
fprintf(stderr, "-javaagent: memory allocation failure.\n");
return JNI_ERR;
}
/*
* Agent_OnLoad is specified to provide the agent options
* argument tail in modified UTF8. However for 1.5.0 this is
* actually in the platform encoding - see 5049313.
*
* Open zip/jar file and parse archive. If can't be opened or
* not a zip file return error. Also if Premain-Class attribute
* isn't present we return an error.
*/
/
/ 读取jar⽂件
attributes = readAttributes(jarfile);
if (attributes == NULL) {
fprintf(stderr, "Error opening zip file or JAR manifest missing : %s\n", jarfile);            free(jarfile);
if (options != NULL) free(options);
return JNI_ERR;
}
// 从jar⽂件中获取Premain-Class
premainClass = getAttribute(attributes, "Premain-Class");
if (premainClass == NULL) {
fprintf(stderr, "Failed to find Premain-Class manifest attribute in %s\n",
jarfile);
free(jarfile);
if (options != NULL) free(options);
freeAttributes(attributes);
return JNI_ERR;
}
/*
* Add to the jarfile
*/
// 把jar⽂件追加到agent的class path中。
appendClassPath(agent, jarfile);
/
*
* The value of the Premain-Class attribute becomes the agent
* class name. The manifest is in UTF8 so need to convert to
* modified UTF8 (see JNI spec).
*/
oldLen = (int)strlen(premainClass);
newLen = modifiedUtf8LengthOfUtf8(premainClass, oldLen);
if (newLen == oldLen) {
premainClass = strdup(premainClass);
} else {
char* str = (char*)malloc( newLen+1 );
if (str != NULL) {
convertUtf8ToModifiedUtf8(premainClass, oldLen, str, newLen);
}
premainClass = str;
}
if (premainClass == NULL) {
fprintf(stderr, "-javaagent: memory allocation failed\n");
free(jarfile);
if (options != NULL) free(options);
freeAttributes(attributes);
return JNI_ERR;
}
/*
* If the Boot-Class-Path attribute is specified then we process
* each relative URL and add it to the bootclasspath.
*/
bootClassPath = getAttribute(attributes, "Boot-Class-Path");
if (bootClassPath != NULL) {
appendBootClassPath(agent, jarfile, bootClassPath);
}
/*
* Convert JAR attributes into agent capabilities
*/
convertCapabilityAtrributes(attributes, agent);

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。