当前位置: 代码迷 >> 综合 >> Java Instrument (二) JVMTI
  详细解决方案

Java Instrument (二) JVMTI

热度:63   发布时间:2023-12-07 23:12:50.0

1 JVMTI

JVMTI 全名JVM Tool Interface,是JVM暴露出来的一些供用户扩展的接口集合。JVMTI是基于事件驱动的,JVM每执行到一定的逻辑就会主动调用一些事件的回调接口,这些接口可以供开发者扩展自己的逻辑。

下面是JVMTI的一些回调接口


typedef struct {/*   50 : VM Initialization Event */jvmtiEventVMInit VMInit;   /*   51 : VM Death Event */jvmtiEventVMDeath VMDeath; /*   52 : Thread Start */jvmtiEventThreadStart ThreadStart;/*   53 : Thread End */jvmtiEventThreadEnd ThreadEnd;  /*   54 : Class File Load Hook */jvmtiEventClassFileLoadHook ClassFileLoadHook; /*   55 : Class Load */jvmtiEventClassLoad ClassLoad; /*   56 : Class Prepare */jvmtiEventClassPrepare ClassPrepare;/*   57 : VM Start Event */jvmtiEventVMStart VMStart;/*   58 : Exception */jvmtiEventException Exception;/*   59 : Exception Catch */jvmtiEventExceptionCatch ExceptionCatch; /*   60 : Single Step */jvmtiEventSingleStep SingleStep;/*   61 : Frame Pop */jvmtiEventFramePop FramePop;/*   62 : Breakpoint */jvmtiEventBreakpoint Breakpoint; /*   63 : Field Access */jvmtiEventFieldAccess FieldAccess;/*   64 : Field Modification */jvmtiEventFieldModification FieldModification; /*   65 : Method Entry */jvmtiEventMethodEntry MethodEntry;/*   66 : Method Exit */jvmtiEventMethodExit MethodExit;/*   67 : Native Method Bind */jvmtiEventNativeMethodBind NativeMethodBind;/*   68 : Compiled Method Load */jvmtiEventCompiledMethodLoad CompiledMethodLoad;/*   69 : Compiled Method Unload */jvmtiEventCompiledMethodUnload CompiledMethodUnload; /*   70 : Dynamic Code Generated */jvmtiEventDynamicCodeGenerated DynamicCodeGenerated; /*   71 : Data Dump Request */jvmtiEventDataDumpRequest DataDumpRequest;/*   72 */jvmtiEventReserved reserved72;/*   73 : Monitor Wait */jvmtiEventMonitorWait MonitorWait;/*   74 : Monitor Waited */jvmtiEventMonitorWaited MonitorWaited;/*   75 : Monitor Contended Enter */jvmtiEventMonitorContendedEnter MonitorContendedEnter;/*   76 : Monitor Contended Entered */jvmtiEventMonitorContendedEntered MonitorContendedEntered;/*   77 */jvmtiEventReserved reserved77;/*   78 */jvmtiEventReserved reserved78; /*   79 */jvmtiEventReserved reserved79; /*   80 : Resource Exhausted */jvmtiEventResourceExhausted ResourceExhausted;/*   81 : Garbage Collection Start */jvmtiEventGarbageCollectionStart GarbageCollectionStart;/*   82 : Garbage Collection Finish */jvmtiEventGarbageCollectionFinish GarbageCollectionFinish;/*   83 : Object Free */jvmtiEventObjectFree ObjectFree;/*   84 : VM Object Allocation */jvmtiEventVMObjectAlloc VMObjectAlloc;
} jvmtiEventCallbacks;


1.1     jvmtiEventVMInit的回调函数

虚拟机在创建create_vm的时候,初始化了JVMTI的环境, JvmtiExport::post_vm_initialized(); 的方法中

void JvmtiExport::post_vm_initialized() {EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" ));// can now enable eventsJvmtiEventController::vm_init();JvmtiEnvIterator it;for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {if (env->is_enabled(JVMTI_EVENT_VM_INIT)) {EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" ));JavaThread *thread  = JavaThread::current();JvmtiThreadEventMark jem(thread);JvmtiJavaThreadEventTransition jet(thread);jvmtiEventVMInit callback = env->callbacks()->VMInit;if (callback != NULL) {(*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread());}}}
}
代码中调用了VMInit的回调函数

1.2     jvmtiEventClassFileLoadHook回调函数

钩子方法是jvmtiEventClassFileLoadHook 的方法,我们可以看代码:在classFileParser的文件中

instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name, Handle class_loader,Handle protection_domain, KlassHandle host_klass, GrowableArray<Handle>* cp_patches, symbolHandle& parsed_name,bool verify, TRAPS) {……if (JvmtiExport::should_post_class_file_load_hook()) {unsigned char* ptr = cfs->buffer();unsigned char* end_ptr = cfs->buffer() + cfs->length();JvmtiExport::post_class_file_load_hook(name, class_loader, protection_domain,&ptr, &end_ptr,&cached_class_file_bytes,&cached_class_file_length);if (ptr != cfs->buffer()) {// JVMTI agent has modified class file data.// Set new class file stream using JVMTI agent modified// class file data.cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source());set_stream(cfs);}}
…
}

在jvmtiexport::post_class_file_load_hook函数最后调用了post_to_env()函数

void post_to_env(JvmtiEnv* env, bool caching_needed) {unsigned char *new_data = NULL;jint new_len = 0;JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader,_h_protection_domain,_h_class_being_redefined);JvmtiJavaThreadEventTransition jet(_thread);JNIEnv* jni_env =  (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)?NULL : jem.jni_env();jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook;if (callback != NULL) {(*callback)(env->jvmti_external(), jni_env,jem.class_being_redefined(),jem.jloader(), jem.class_name(),jem.protection_domain(),_curr_len, _curr_data,&new_len, &new_data);}......}

函数中调用了jvmtiEventClassFileLoadHook 的钩子回调函数,也就是刚才在结构体中定义的jvmtiEventCallbacks

  相关解决方案