JVMTI Class load callback not being called on Windows, but works on Linux
serguei.spitsyn at oracle.com
serguei.spitsyn at oracle.com
Tue Jan 12 03:18:29 UTC 2021
Hi Charlie,
It is hard to say what is wrong from the information you provided.
I agree with Mikael the following lines look incorrect:
assert(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)) ==
JVMTI_ERROR_NONE);
assert(jvmti->SetEventNotificationMode(JVMTI_ENABLE,
JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, nullptr) == JVMTI_ERROR_NONE);
I guess, they won't be executed in the release/product mode.
So, you may want to replace the asserts which normal checks (working in
any mode) of the returned values.
In general, your code does what is needed to enable the CFLH events.
Q1:
if (res != JNI_OK || jvmti==nullptr) {
fprintf(stderr,"Unable to get JVMTI!");
}
Do you see the above is printed in the output?
I'd also recommend to add more tracing to make sure everything is
executed as you expect.
Good luck with your project!
Thanks,
Serguei
On 1/11/21 05:59, Daniel D. Daugherty 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