JVMTI Class load callback not being called on Windows, but works on Linux

Serguei Spitsyn serguei.spitsyn at oracle.com
Wed Dec 1 21:57:48 UTC 2021


Hi Charlie,

I do not see any obvious errors in your code except what Mikael mentioned below.
Could you, please, check if asserts are really enabled in your runs on Windows?
Also, I agree with Mikael that it would be better to get rid of these asserts or
refactor the code to use asserts only to check results like below:
    jvmtiError err = jvmti->AddCapabilities(&capabilities);
    assert(res == JVMTI_ERROR_NONE);

Also, what are your command-line options?

Thanks,
Serguei

On 12/1/21, 1:17 AM, "hotspot-dev on behalf of Daniel D. Daugherty" <hotspot-dev-retn at openjdk.java.net on behalf of daniel.daugherty at oracle.com> wrote:

    Redirecting to the serviceability-dev at ... alias since JVM/TI is maintained
    by the Serviceability team...
    
    Dan
    
    On 1/10/21 6:09 PM, Mikael Vidstedt wrote:
    > Just a control question: Are you *sure* asserts are actually enabled? Having actual application logic in an assert is normally a bad idea because if/when you compile the release/production version with asserts disabled the application behavior will change.
    >
    > Cheers,
    > Mikael
    >
    >> On Jan 10, 2021, at 8:33 AM, Charlie <cvdcamilleri at gmail.com> wrote:
    >>
    >> Hi,
    >>
    >> I have a working jvmti agent on Linux (Java(TM) SE Runtime Environment (build 1.8.0_271-b09)) that hooks the class load event.
    >>
    >> This same agent compiled for windows claims to work (all asserts pass), but my hook never gets called, is anyone able to tell me why?
    >>
    >> I register my callback like so:
    >>
    >> jint res = vm->GetEnv(reinterpret_cast<void **>(&jvmti), JVMTI_VERSION_1);
    >>      if (res != JNI_OK || jvmti==nullptr) {
    >>          fprintf(stderr,"Unable to get JVMTI!");
    >>      }
    >>      assert(res == JVMTI_ERROR_NONE);
    >>
    >>      jvmtiCapabilities capabilities = {0};
    >>      capabilities.can_retransform_classes=1;
    >>      capabilities.can_generate_all_class_hook_events  = 1;
    >>
    >>      assert(jvmti->AddCapabilities(&capabilities) == JVMTI_ERROR_NONE);
    >>
    >>      jvmtiEventCallbacks callbacks;
    >>      memset(&callbacks,0,sizeof(callbacks));
    >>      callbacks.ClassFileLoadHook = &class_file_load_hook_handler;
    >>      assert(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)) == JVMTI_ERROR_NONE);
    >>      assert(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, nullptr) == JVMTI_ERROR_NONE);
    >>
    >> The callback itself is as follows:
    >>
    >> static void JNICALL class_file_load_hook_handler(
    >>          jvmtiEnv* jvmti,
    >>          JNIEnv* env,
    >>          jclass class_being_redefined,
    >>          jobject loader,
    >>          const char* name,
    >>          jobject protection_domain,
    >>          jint class_data_len,
    >>          const unsigned char* class_data,
    >>          jint* new_class_data_len,
    >>          unsigned char** new_class_data
    >> ) {
    >>      if (name == nullptr) {
    >>          return;
    >>      }
    >>
    >>      printf("loaded %s\n",name);
    >>
    >> }
    >>
    >> (to clarify, all JNI functions in the lib work fine)
    >>
    >> The Windows machine's java version string is this:
    >>
    >> java version "1.8.0_271"
    >> Java(TM) SE Runtime Environment (build 1.8.0_271-b09)
    >> Java HotSpot(TM) 64-Bit Server VM (build 25.271-b09, mixed mode)
    >>
    
    



More information about the serviceability-dev mailing list