Advertisement
Guest User

Untitled

a guest
Mar 20th, 2011
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.97 KB | None | 0 0
  1. #include <iostream>
  2. #include <jvmti.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6.  
  7. #include "agentserver.h"
  8.  
  9.  
  10. /* ------------------------------------------------------------------- */
  11. /* Some constant maximum sizes */
  12.  
  13. #define MAX_TOKEN_LENGTH        16
  14. #define MAX_THREAD_NAME_LENGTH  512
  15. #define MAX_METHOD_NAME_LENGTH  1024
  16.  
  17. static jvmtiEnv *jvmti = NULL;
  18. static jvmtiCapabilities capa;
  19.  
  20. /* Global agent data structure */
  21.  
  22. typedef struct {
  23.     /* JVMTI Environment */
  24.     jvmtiEnv      *jvmti;
  25.     jboolean       vm_is_started;
  26.     /* Data access Lock */
  27.     jrawMonitorID  lock;
  28. } GlobalAgentData;
  29.  
  30. static GlobalAgentData *gdata;
  31.  
  32.  
  33. static jlong combined_size;
  34. static int num_class_refs;
  35. static int num_field_refs;
  36. static int num_array_refs;
  37. static int num_classloader_refs;
  38. static int num_signer_refs;
  39. static int num_protection_domain_refs;
  40. static int num_interface_refs;
  41. static int num_static_field_refs;
  42. static int num_constant_pool_refs;
  43.  
  44.  
  45. /* Every JVMTI interface returns an error code, which should be checked
  46.  *   to avoid any cascading errors down the line.
  47.  *   The interface GetErrorName() returns the actual enumeration constant
  48.  *   name, making the error messages much easier to understand.
  49.  */
  50. static void
  51. check_jvmti_error(jvmtiEnv *jvmti, jvmtiError errnum, const char *str)
  52. {
  53.     if ( errnum != JVMTI_ERROR_NONE ) {
  54.         char       *errnum_str;
  55.  
  56.         errnum_str = NULL;
  57.         jvmti->GetErrorName(errnum, &errnum_str);
  58.  
  59.         printf("ERROR: JVMTI: %d(%s): %s\n", errnum, (errnum_str==NULL?"Unknown":errnum_str), (str==NULL?"":str));
  60.     }
  61. }
  62.  
  63.  
  64. /* Enter a critical section by doing a JVMTI Raw Monitor Enter */
  65. static void
  66. enter_critical_section(jvmtiEnv *jvmti)
  67. {
  68.     jvmtiError error;
  69.  
  70.     error = jvmti->RawMonitorEnter(gdata->lock);
  71.     check_jvmti_error(jvmti, error, "Cannot enter with raw monitor");
  72. }
  73.  
  74. /* Exit a critical section by doing a JVMTI Raw Monitor Exit */
  75. static void
  76. exit_critical_section(jvmtiEnv *jvmti)
  77. {
  78.     jvmtiError error;
  79.  
  80.     error = jvmti->RawMonitorExit(gdata->lock);
  81.     check_jvmti_error(jvmti, error, "Cannot exit with raw monitor");
  82. }
  83.  
  84. void describe(jvmtiError err) {
  85.       jvmtiError err0;
  86.       char *descr;
  87.       err0 = jvmti->GetErrorName(err, &descr);
  88.       if (err0 == JVMTI_ERROR_NONE) {
  89.           printf(descr);
  90.       } else {
  91.           printf("error [%d]", err);
  92.       }
  93.  }
  94.  
  95.  
  96. // Exception callback
  97.  static void JNICALL callbackException(jvmtiEnv *jvmti_env, JNIEnv* env, jthread thr, jmethodID method, jlocation location, jobject exception, jmethodID catch_method, jlocation catch_location) {
  98. enter_critical_section(jvmti); {
  99.  
  100.       jvmtiError err, err1, err2;
  101.       jvmtiThreadInfo info, info1;
  102.       jvmtiThreadGroupInfo groupInfo;
  103.       jint num_monitors;
  104.       jobject *arr_monitors;
  105.  
  106.       jvmtiFrameInfo frames[5];
  107.       jint count;
  108.       jint flag = 0;
  109.       jint thr_st_ptr;
  110.       jint thr_count;
  111.       jthread *thr_ptr;
  112.  
  113.       jvmtiError err3;
  114.       char *name;
  115.       char *sig;
  116.       char *gsig;
  117.  
  118.       err3  = jvmti->GetMethodName(method, &name, &sig, &gsig);
  119.       if (err3  != JVMTI_ERROR_NONE) {
  120. //          printf("GetMethodName:%d\n", err);
  121.           return;
  122.       }
  123.  
  124. //      printf("Got Exception from Method:%s%s\n", name, sig);
  125.  
  126.  
  127.       err =jvmti->GetThreadInfo(thr, &info);
  128.       if (err != JVMTI_ERROR_NONE) {
  129.           printf("(GetThreadInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err);
  130.           describe(err);
  131.                  jvmtiPhase phase;
  132.                  jvmtiError phaseStat;
  133.                  phaseStat = jvmti->GetPhase(&phase);
  134.                  printf("    current phase is %d\n", phase);
  135.           printf("\n");
  136.  
  137.       }
  138.  
  139.  
  140.       if (err == JVMTI_ERROR_NONE) {
  141.         err1 = jvmti->GetThreadGroupInfo(info.thread_group, &groupInfo);
  142.                  if (err1 != JVMTI_ERROR_NONE)
  143.                  {
  144.                         printf("(GetThreadGroupInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err);
  145.                         describe(err);
  146.                         printf("\n");
  147.                  }
  148.              }
  149.  
  150. //      if ((err == JVMTI_ERROR_NONE ) && (err1 == JVMTI_ERROR_NONE ) )
  151. //             {
  152. //                 printf("Current Thread is : %s and it belongs to Thread Group :  %s\n", info.name, groupInfo.name);
  153. //             }
  154.  
  155.  
  156.      err = jvmti->GetOwnedMonitorInfo(thr, &num_monitors, &arr_monitors);
  157.       if (err != JVMTI_ERROR_NONE) {
  158.           printf("(GetThreadInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err);
  159.           describe(err);
  160.           printf("\n");
  161.  
  162.       }
  163.  
  164.      std::cout << "Number of Monitors Owned by this thread : " << num_monitors << "\n";
  165.  
  166. //     /* Get Thread Status */
  167. //     err = jvmti->GetThreadState(thr, &thr_st_ptr);
  168. //     if (err != JVMTI_ERROR_NONE) {
  169. //          printf("(GetThreadInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err);
  170. //          describe(err);
  171. //          printf("\n");
  172.  
  173. //      }
  174.  
  175. //     if (err == JVMTI_ERROR_NONE) {
  176. //        printf("Thread Status\n");
  177. //        printf("==============\n");
  178. //        if  ( thr_st_ptr & JVMTI_THREAD_STATE_ALIVE) {
  179. //            printf("Thread %s is Alive\n", info.name);
  180. //                flag = 1;
  181. //        }
  182.  
  183. //        if  ( thr_st_ptr & JVMTI_THREAD_STATE_TERMINATED) {
  184.  
  185. //           printf("Thread %s has been Terminated\n", info.name);
  186. //                flag = 1;
  187. //        }
  188.  
  189. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_RUNNABLE ) {
  190.  
  191. //           printf("Thread %s is Runnable\n", info.name);
  192. //                flag = 1;
  193. //        }
  194.  
  195. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_WAITING ) {
  196. //           printf("Thread %s waiting\n", info.name);
  197. //                flag = 1;
  198. //        }
  199.  
  200. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_WAITING_INDEFINITELY ) {
  201. //           printf("Thread %s waiting indefinitely\n", info.name);
  202. //                flag = 1;
  203. //        }
  204.  
  205. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT ) {
  206. //           printf("Thread %s waiting with Timeout\n", info.name);
  207. //                flag = 1;
  208. //        }
  209.  
  210. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_SLEEPING ) {
  211. //           printf("Thread %s Sleeping \n", info.name);
  212. //                flag = 1;
  213. //        }
  214.  
  215. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_IN_OBJECT_WAIT ) {
  216. //           printf("Thread %s is in Object Wait \n", info.name);
  217. //                flag = 1;
  218. //        }
  219. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_PARKED ) {
  220. //           printf("Thread %s is Parked \n", info.name);
  221. //                flag = 1;
  222. //        }
  223. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER ) {
  224. //           printf("Thread %s is blocked on monitor enter \n", info.name);
  225. //                flag = 1;
  226. //        }
  227. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_SUSPENDED ) {
  228. //           printf("Thread %s is Suspended \n", info.name);
  229. //                flag = 1;
  230. //        }
  231. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_INTERRUPTED ) {
  232. //           printf("Thread %s is Interrupted \n", info.name);
  233. //                flag = 1;
  234. //        }
  235. //        if ( thr_st_ptr & JVMTI_THREAD_STATE_IN_NATIVE ) {
  236.  
  237. //           printf("Thread %s is in Native \n", info.name);
  238. //                flag = 1;
  239. //        }
  240. //         if ( flag != 1 )  {
  241. //             std::cout << "Illegal value " << thr_st_ptr << " for Thread State\n";
  242. //        }
  243.  
  244. //        }
  245.  
  246. //     /* Get All Threads */
  247. //     err = jvmti->GetAllThreads(&thr_count, &thr_ptr);
  248. //     if (err != JVMTI_ERROR_NONE) {
  249. //          printf("(GetThreadInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err);
  250. //          describe(err);
  251. //          printf("\n");
  252.  
  253. //      }
  254. //      if (err == JVMTI_ERROR_NONE && thr_count >= 1) {
  255. //        int i = 0;
  256. //        std::cout << "Thread Count: " << thr_count << "\n";
  257.  
  258. //        for ( i=0; i < thr_count; i++) {
  259.  
  260. //            /* Make sure the stack variables are garbage free */
  261. //            (void)memset(&info1,0, sizeof(info1));
  262.  
  263. //            err1 = jvmti->GetThreadInfo(thr_ptr[i], &info1);
  264. //            if (err1 != JVMTI_ERROR_NONE) {
  265. //                printf("(GetThreadInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err1);
  266. //                describe(err1);
  267. //                printf("\n");
  268. //            }
  269.  
  270. //            std::cout << "Running Thread#" << i+1 << ": " << info1.name << ", Priority: " << info1.priority << ", context class loader:" << (info1.context_class_loader == NULL ? ": NULL" : "Not Null");
  271.  
  272.  
  273.  
  274. //            /* Every string allocated by JVMTI needs to be freed */
  275.  
  276. //            err2 = jvmti->Deallocate((unsigned char*)info1.name);
  277. //            if (err2 != JVMTI_ERROR_NONE) {
  278. //                printf("(GetThreadInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err2);
  279. //                describe(err2);
  280. //                printf("\n");
  281. //            }
  282.  
  283.  
  284.  
  285. //        }
  286. //      }
  287.  
  288.  
  289. //     /* Get Stack Trace */
  290. //      err = jvmti->GetStackTrace(thr,(jint)0,(jint)5,&frames[0],&count);
  291.  
  292. //     if (err != JVMTI_ERROR_NONE) {
  293. //          printf("(GetThreadInfo) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, err);
  294. //          describe(err);
  295. //          printf("\n");
  296.  
  297. //      }
  298. //     std::cout << "Number of records filled: " << count << "\n";
  299.  
  300. //     if (err == JVMTI_ERROR_NONE && count >=1) {
  301.  
  302. //        char *methodName;
  303. //        methodName = "yet_to_call()";
  304. //        char *declaringClassName;
  305. //        jclass declaring_class;
  306.  
  307. //        int i=0;
  308.  
  309. //        printf("Exception Stack Trace\n");
  310. //        printf("=====================\n");
  311. //        std::cout << "Stack Trace Depth: " << count << "\n";
  312.  
  313. //        for ( i=0; i < count; i++) {
  314. //                err = jvmti->GetMethodName(frames[i].method, &methodName, NULL, NULL);
  315. //                if (err == JVMTI_ERROR_NONE) {
  316.  
  317. //                         err = jvmti->GetMethodDeclaringClass(frames[i].method, &declaring_class);
  318. //                         err = jvmti->GetClassSignature(declaring_class, &declaringClassName, NULL);
  319. //                         if (err == JVMTI_ERROR_NONE) {
  320. //                                 printf("at method %s() in class %s\n", methodName, declaringClassName);
  321. //                         }
  322. //                }
  323.  
  324. //        }
  325. //        printf("\n");
  326.  
  327. //        err = jvmti->Deallocate((unsigned char*)methodName);
  328. //        err = jvmti->Deallocate((unsigned char*)declaringClassName);
  329. //    }
  330.  } exit_critical_section(jvmti);
  331.  
  332.  }
  333. // VM Death callback
  334.      static void JNICALL callbackVMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env)
  335.      {
  336.          enter_critical_section(jvmti); {
  337.  
  338.                 printf("Got VM Death event\n");
  339.  
  340.         } exit_critical_section(jvmti);
  341.  
  342.      }
  343.  
  344.  
  345. /* Get a name for a jthread */
  346. static void get_thread_name(jvmtiEnv *jvmti, jthread thread, char *tname, int maxlen)
  347. {
  348.     jvmtiThreadInfo info;
  349.     jvmtiError      error;
  350.  
  351.     /* Make sure the stack variables are garbage free */
  352.     (void)memset(&info,0, sizeof(info));
  353.  
  354.     /* Assume the name is unknown for now */
  355.     (void)strcpy(tname, "Unknown");
  356.  
  357.     /* Get the thread information, which includes the name */
  358.     error = jvmti->GetThreadInfo(thread, &info);
  359.     check_jvmti_error(jvmti, error, "Cannot get thread info");
  360.  
  361.     /* The thread might not have a name, be careful here. */
  362.     if ( info.name != NULL ) {
  363.         int len;
  364.  
  365.         /* Copy the thread name into tname if it will fit */
  366.         len = (int)strlen(info.name);
  367.         if ( len < maxlen ) {
  368.             (void)strcpy(tname, info.name);
  369.         }
  370.  
  371.         /* Every string allocated by JVMTI needs to be freed */
  372.             error = jvmti->Deallocate((unsigned char*)info.name);
  373.             if (error != JVMTI_ERROR_NONE) {
  374.                 printf("(get_thread_name) Error expected: %d, got: %d\n", JVMTI_ERROR_NONE, error);
  375.                 describe(error);
  376.                 printf("\n");
  377.             }
  378.  
  379.     }
  380. }
  381.  
  382.  
  383. // VM init callback
  384.      static void JNICALL callbackVMInit(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread)
  385.      {
  386.         enter_critical_section(jvmti); {
  387.  
  388.         char  tname[MAX_THREAD_NAME_LENGTH];
  389.         static jvmtiEvent events[] = { JVMTI_EVENT_THREAD_START, JVMTI_EVENT_THREAD_END };
  390.         int        i;
  391.         jvmtiFrameInfo frames[5];
  392.         jvmtiError err, err1;
  393.         jvmtiError error;
  394.         jint count;
  395.  
  396.         /* The VM has started. */
  397.         printf("Got VM init event\n");
  398.         get_thread_name(jvmti_env , thread, tname, sizeof(tname));
  399.         printf("callbackVMInit:  %s thread\n", tname);
  400.  
  401.  
  402.             error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_EXCEPTION, (jthread)NULL);
  403.             check_jvmti_error(jvmti_env, error, "Cannot set event notification");
  404.  
  405.  
  406.  
  407.      } exit_critical_section(jvmti);
  408.  
  409.      }
  410.  
  411.  
  412. /* JVMTI callback function. */
  413. static jvmtiIterationControl JNICALL
  414. reference_object(jvmtiObjectReferenceKind reference_kind,
  415.                 jlong class_tag, jlong size, jlong* tag_ptr,
  416.                 jlong referrer_tag, jint referrer_index, void *user_data)
  417. {
  418.  
  419.         combined_size = combined_size + size;
  420.  
  421.         switch (reference_kind) {
  422.  
  423.                 case JVMTI_REFERENCE_CLASS:
  424.                         num_class_refs = num_class_refs + 1;
  425.                         break;
  426.                 case JVMTI_REFERENCE_FIELD:
  427.                         num_field_refs = num_field_refs + 1;
  428.                         break;
  429.                 case JVMTI_REFERENCE_ARRAY_ELEMENT:
  430.                         num_array_refs = num_array_refs + 1;
  431.                         break;
  432.                 case JVMTI_REFERENCE_CLASS_LOADER:
  433.                         num_classloader_refs = num_classloader_refs + 1;
  434.                         break;
  435.                 case JVMTI_REFERENCE_SIGNERS:
  436.                         num_signer_refs = num_signer_refs + 1;
  437.                         break;
  438.                 case JVMTI_REFERENCE_PROTECTION_DOMAIN:
  439.                         num_protection_domain_refs = num_protection_domain_refs + 1;
  440.                         break;
  441.                 case JVMTI_REFERENCE_INTERFACE:
  442.                         num_interface_refs = num_interface_refs + 1;
  443.                         break;
  444.                 case JVMTI_REFERENCE_STATIC_FIELD:
  445.                         num_static_field_refs = num_static_field_refs + 1;
  446.                         break;
  447.                 case JVMTI_REFERENCE_CONSTANT_POOL:
  448.                         num_constant_pool_refs = num_constant_pool_refs + 1;
  449.                         break;
  450.                 default:
  451.                         break;
  452.         }
  453.  
  454.  
  455.     return JVMTI_ITERATION_CONTINUE;
  456. }
  457.  
  458.  
  459. static void JNICALL callbackVMObjectAlloc(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, jobject object, jclass object_klass, jlong size) {
  460.  
  461.  
  462.         char *methodName;
  463.         char *className;
  464.         char *declaringClassName;
  465.         jclass declaring_class;
  466.         jvmtiError err;
  467.  
  468.  
  469.         if (size > 50) {
  470.                 err = jvmti->GetClassSignature(object_klass, &className, NULL);
  471.  
  472.                 if (className != NULL) {
  473. //                        printf("\ntype %s object allocated with size %d\n", className, (jint)size);
  474.                 }
  475.  
  476.                 //print stack trace
  477.                 jvmtiFrameInfo frames[5];
  478.                 jint count;
  479.                 int i;
  480.  
  481.  
  482.                 err = jvmti->GetStackTrace(NULL, (jint)0, (jint)5, &frames[0], &count);
  483.                 if (err == JVMTI_ERROR_NONE && count >= 1) {
  484.  
  485.                         for (i = 0; i < count; i++) {
  486.                                 err = jvmti->GetMethodName(frames[i].method, &methodName, NULL, NULL);
  487.                                 if (err == JVMTI_ERROR_NONE) {
  488.  
  489.                                         err = jvmti->GetMethodDeclaringClass(frames[i].method, &declaring_class);
  490.                                         err = jvmti->GetClassSignature(declaring_class, &declaringClassName, NULL);
  491.                                         if (err == JVMTI_ERROR_NONE) {
  492. //                                                printf("at method %s in class %s\n", methodName, declaringClassName);
  493.                                         }
  494.                                 }
  495.                         }
  496.                 }
  497.  
  498.                 //reset counters
  499.                 combined_size  = 0;
  500.                 num_class_refs = 0;
  501.                 num_field_refs = 0;
  502.                 num_array_refs = 0;
  503.                 num_classloader_refs = 0;
  504.                 num_signer_refs = 0;
  505.                 num_protection_domain_refs = 0;
  506.                 num_interface_refs = 0;
  507.                 num_static_field_refs = 0;
  508.                 num_constant_pool_refs = 0;
  509.  
  510.                 err = jvmti->IterateOverObjectsReachableFromObject(object, &reference_object, NULL);
  511.                 if ( err != JVMTI_ERROR_NONE ) {
  512.                         printf("Cannot iterate over reachable objects\n");
  513.                 }
  514.  
  515. //                printf("\nThis object has references to objects of combined size %d\n", (jint)combined_size);
  516. //                printf("This includes %d classes, %d fields, %d arrays, %d classloaders, %d signers arrays,\n", num_class_refs, num_field_refs, num_array_refs, num_classloader_refs, num_signer_refs);
  517. //                printf("%d protection domains, %d interfaces, %d static fields, and %d constant pools.\n\n", num_protection_domain_refs, num_interface_refs, num_static_field_refs, num_constant_pool_refs);
  518.  
  519.                 err = jvmti->Deallocate((unsigned char*)className);
  520.                 err = jvmti->Deallocate((unsigned char*)methodName);
  521.                 err = jvmti->Deallocate((unsigned char*)declaringClassName);
  522.         }
  523. }
  524.  
  525.  
  526.  
  527. JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)
  528.  {
  529.       static GlobalAgentData data;
  530.       jvmtiError error;
  531.       jint res;
  532.       jvmtiEventCallbacks callbacks;
  533.  
  534. /*
  535.  * Establish server socket
  536.  */
  537.       AgentServer server;
  538.  
  539.     /* Setup initial global agent data area
  540.      * Use of static/extern data should be handled carefully here.
  541.      * We need to make sure that we are able to cleanup after ourselves
  542.      * so anything allocated in this library needs to be freed in
  543.      * the Agent_OnUnload() function.
  544.      */
  545.      (void)memset((void*)&data, 0, sizeof(data));
  546.      gdata = &data;
  547.  
  548.       /*  We need to first get the jvmtiEnv* or JVMTI environment */
  549.  
  550.       res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_0);
  551.  
  552.       if (res != JNI_OK || jvmti == NULL) {
  553.         /* This means that the VM was unable to obtain this version of the
  554.          *   JVMTI interface, this is a fatal error.
  555.          */
  556.         printf("ERROR: Unable to access JVMTI Version 1 (0x%x),"
  557.                 " is your J2SE a 1.5 or newer version?"
  558.                 " JNIEnv's GetEnv() returned %d\n",
  559.                JVMTI_VERSION_1, res);
  560.  
  561.       }
  562.  
  563.       /* Here we save the jvmtiEnv* for Agent_OnUnload(). */
  564.     gdata->jvmti = jvmti;
  565.  
  566.  
  567.     (void)memset(&capa, 0, sizeof(jvmtiCapabilities));
  568.     capa.can_signal_thread = 1;
  569.     capa.can_get_owned_monitor_info = 1;
  570.     capa.can_generate_method_entry_events = 1;
  571.     capa.can_generate_exception_events = 1;
  572.     capa.can_generate_vm_object_alloc_events = 1;
  573.     capa.can_tag_objects = 1;
  574.  
  575.     error = jvmti->AddCapabilities(&capa);
  576.     check_jvmti_error(jvmti, error, "Unable to get necessary JVMTI capabilities.");
  577.  
  578.  
  579.     (void)memset(&callbacks, 0, sizeof(callbacks));
  580.     callbacks.VMInit = &callbackVMInit; /* JVMTI_EVENT_VM_INIT */
  581.     callbacks.VMDeath = &callbackVMDeath; /* JVMTI_EVENT_VM_DEATH */
  582.     callbacks.Exception = &callbackException;/* JVMTI_EVENT_EXCEPTION */
  583.     callbacks.VMObjectAlloc = &callbackVMObjectAlloc;/* JVMTI_EVENT_VM_OBJECT_ALLOC */
  584.  
  585.  
  586.     error = jvmti->SetEventCallbacks(&callbacks, (jint)sizeof(callbacks));
  587.     check_jvmti_error(jvmti, error, "Cannot set jvmti callbacks");
  588.  
  589.     /* At first the only initial events we are interested in are VM
  590.      *   initialization, VM death, and Class File Loads.
  591.      *   Once the VM is initialized we will request more events.
  592.     */
  593.     error = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
  594.                           JVMTI_EVENT_VM_INIT, (jthread)NULL);
  595.     error = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
  596.                           JVMTI_EVENT_VM_DEATH, (jthread)NULL);
  597.     error = jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_OBJECT_ALLOC, (jthread)NULL);
  598.     check_jvmti_error(jvmti, error, "Cannot set event notification");
  599.  
  600.  
  601.     /* Here we create a raw monitor for our use in this agent to
  602.      *   protect critical sections of code.
  603.      */
  604.     error = jvmti->CreateRawMonitor("agent data", &(gdata->lock));
  605.     check_jvmti_error(jvmti, error, "Cannot create raw monitor");
  606.  
  607.     /* We return JNI_OK to signify success */
  608.     return JNI_OK;
  609.  
  610.  
  611.  }
  612.  
  613.  
  614. /* Agent_OnUnload: This is called immediately before the shared library is
  615.  *   unloaded. This is the last code executed.
  616.  */
  617. JNIEXPORT void JNICALL
  618. Agent_OnUnload(JavaVM *vm)
  619. {
  620.         /* Make sure all malloc/calloc/strdup space is freed */
  621.  
  622. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement