Java Instrument (三) 钩子函数

1 注册钩子函数

我们看看这个钩子函数jvmtiEventClassFileLoadHook 啥时候注册的,回到刚才创建新的JPLISAgent代码中

JPLISInitializationError  createNewJPLISAgent(JavaVM * vm, JPLISAgent **agent_ptr) {
    JPLISInitializationError initerror       = JPLIS_INIT_ERROR_NONE;
    jvmtiEnv *               jvmtienv        = NULL;
    jint                     jnierror        = JNI_OK;
    *agent_ptr = NULL;
    jnierror = (*vm)->GetEnv(vm,(void **) &jvmtienv,JVMTI_VERSION);
    if ( jnierror != JNI_OK ) {
        initerror = JPLIS_INIT_ERROR_CANNOT_CREATE_NATIVE_AGENT;
    } else {
        JPLISAgent * agent = allocateJPLISAgent(jvmtienv);
        if ( agent == NULL ) {
            initerror = JPLIS_INIT_ERROR_ALLOCATION_FAILURE;
        } else {
            initerror = initializeJPLISAgent( agent,
                                               vm,
                                               jvmtienv);
            if ( initerror == JPLIS_INIT_ERROR_NONE ) {
                *agent_ptr = agent;
            } else {
                deallocateJPLISAgent(jvmtienv, agent);
            }
        }
        /* don't leak envs */
        if ( initerror != JPLIS_INIT_ERROR_NONE ) {
            jvmtiError jvmtierror = (*jvmtienv)->DisposeEnvironment(jvmtienv);
            jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
        }
    }
    return initerror;
}

函数initializeJPLISAgent初始化了PLISAgent

JPLISInitializationError initializeJPLISAgent(   JPLISAgent *    agent,JavaVM *        vm,jvmtiEnv *      jvmtienv) {
   ……
    checkCapabilities(agent);
    jvmtierror == (*jvmtienv)->GetPhase(jvmtienv, &phase);
    jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    if (phase == JVMTI_PHASE_LIVE) {
        return JPLIS_INIT_ERROR_NONE;
    }
    /* now turn on the VMInit event */
    if ( jvmtierror == JVMTI_ERROR_NONE ) {
        jvmtiEventCallbacks callbacks;
        memset(&callbacks, 0, sizeof(callbacks));
        callbacks.VMInit = &eventHandlerVMInit;
        jvmtierror = (*jvmtienv)->SetEventCallbacks( jvmtienv, &callbacks,  sizeof(callbacks));

        jplis_assert(jvmtierror == JVMTI_ERROR_NONE);
    }
  ……
}

JPLISAgent里首先注册了一个VMInit的初始化函数eventHandlerVMInit,跟踪eventHandlerVMInit函数

void JNICALL
eventHandlerVMInit( jvmtiEnv *      jvmtienv,
                    JNIEnv *        jnienv,
                    jthread         thread) {
    JPLISEnvironment * environment  = NULL;
    jboolean           success      = JNI_FALSE;

    environment = getJPLISEnvironment(jvmtienv);

    /* process the premain calls on the all the JPL agents */
    if ( environment != NULL ) {
        jthrowable outstandingException = preserveThrowable(jnienv);
        success = processJavaStart( environment->mAgent,
                                    jnienv);
        restoreThrowable(jnienv, outstandingException);
    }

    /* if we fail to start cleanly, bring down the JVM */
    if ( !success ) {
        abortJVM(jnienv, JPLIS_ERRORMESSAGE_CANNOTSTART);
    }
}

在processJavaStart里

jboolean
processJavaStart(   JPLISAgent *    agent,JNIEnv *        jnienv) {
    jboolean    result;
    result = initializeFallbackError(jnienv);
    jplis_assert(result);
    if ( result ) {
        result = createInstrumentationImpl(jnienv, agent);
        jplis_assert(result);
    }
    if ( result ) {
        result = setLivePhaseEventHandlers(agent);
        jplis_assert(result);
    }
    if ( result ) {
        result = startJavaAgent(agent, jnienv, agent->mAgentClassName, agent->mOptionsString,agent->mPremainCaller);
    }
    if ( result ) {
        deallocateCommandLineData(agent);
    }
    return result;
}
在setLivePhaseEventHandler函数中注册了callbacks.ClassFileLoadHook = &eventHandlerClassFileLoadHook;  



你可能感兴趣的:(java,instrument,钩子函数)