#include #include #include #include #include "jni.h" #include "jvmti.h" static char * getErrorName (jvmtiEnv * jvmti, jvmtiError errnum) { jvmtiError err; char *name; err = (*jvmti)->GetErrorName (jvmti, errnum, &name); if (err != JVMTI_ERROR_NONE) { printf ("ERROR: JVMTI GetErrorName error err=%d\n", err); abort (); } return name; } /* Check for JVMTI error */ #define CHECK_JVMTI_ERROR(jvmti, err) \ checkJvmtiError(jvmti, err, __FILE__, __LINE__) static void checkJvmtiError (jvmtiEnv * jvmti, jvmtiError err, char *file, int line) { if (err != JVMTI_ERROR_NONE) { char *name; name = getErrorName (jvmti, err); printf ("ERROR: JVMTI error err=%d(%s) in %s:%d\n", err, name, file, line); abort (); } } static jint JNICALL stringCallback (jlong class_tag, jlong size, jlong* tag_ptr, const jchar* value, jint value_length, void* user_data) { return 0; } static void JNICALL scanStrings (jvmtiEnv * jvmti, JNIEnv* jni_env, jthread thread) { static jvmtiHeapCallbacks callbacks; callbacks.string_primitive_value_callback = stringCallback; int err = (*jvmti)->IterateThroughHeap(jvmti, 0, NULL, &callbacks, NULL); CHECK_JVMTI_ERROR (jvmti, err); } JNIEXPORT jint JNICALL Agent_OnLoad (JavaVM * vm, char *options, void *reserved) { jint rc; jvmtiError err; jvmtiCapabilities capabilities; jvmtiEventCallbacks callbacks; jvmtiEnv *jvmti; jvmti = NULL; rc = (*vm)->GetEnv (vm, (void **) &jvmti, JVMTI_VERSION); if (rc != JNI_OK) { printf ("ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc); return -1; } memset (&capabilities, 0, sizeof (jvmtiCapabilities)); capabilities.can_tag_objects = 1; err = (*jvmti)->AddCapabilities (jvmti, &capabilities); CHECK_JVMTI_ERROR (jvmti, err); memset (&callbacks, 0, sizeof (callbacks)); callbacks.ThreadEnd = &scanStrings; err = (*jvmti)->SetEventCallbacks (jvmti, &callbacks, sizeof (callbacks)); CHECK_JVMTI_ERROR (jvmti, err); err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_THREAD_END, NULL); CHECK_JVMTI_ERROR (jvmti, err); printf ("\n\nDemo JVMTI agent loaded and initialized\n\n"); return 0; } JNIEXPORT void JNICALL Agent_OnUnload (JavaVM * vm) { }