2 Replies Latest reply on Jan 31, 2010 10:48 PM by 843810

    METHOD_ENTRY and METHOD_EXIT events out of order?

      I noticed a problem with my agent, it seems like I'm getting a weird problem with METHOD_ENTRY and METHOD_EXIT events. I would expect them to come paired, one METHOD_ENTRY to one METHOD_EXIT, but sometimes I get a METHOD_EXIT for a method which I never saw a METHOD_ENTRY. I wrote a really simple agent to confirm this (at the end). I ran this on a single threaded java program, so it would not appear to be a threading issue.

      Has any one else observed this phenomenon, and is there a way around it? I need to know the order in which these events occur.
      #include <jvmti.h>
      #include <jni.h>
      #include <jni_md.h>
      #include <stdio.h>
      #include <string.h>
      static FILE* traceOutput;
      static void JNICALL cbMethodExit(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, jmethodID method, jboolean was_popped_by_exception, jvalue return_value){
                     fprintf(traceOutput, "E 0x%lX\n", (unsigned long)method);
      static void JNICALL cbMethodEntry(jvmtiEnv *env, JNIEnv* jni_env, jthread thread, jmethodID method){
                     fprintf(traceOutput, "M 0x%lX\n", (unsigned long)method);
      void setCapabilities(jvmtiEnv *env){
           jvmtiCapabilities capa;
           jvmtiError error;
           (void)memset(&capa,0, sizeof(capa));
          /*Tell the JVM what capabilities we want*/
               capa.can_generate_method_entry_events = 1;
              capa.can_generate_method_exit_events = 1;
             (*env)->AddCapabilities(env, &capa);
      jint Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
               jvmtiEnv *env;
               jvmtiError error;
               jint res;
               jvmtiEventCallbacks    callbacks;
           res =  (*vm)->GetEnv(vm, (void**)&env, JVMTI_VERSION_1);
               /*Set the callbacks*/
               (void)memset(&callbacks,0, sizeof(callbacks));                   
           callbacks.MethodEntry   = &cbMethodEntry;
           callbacks.MethodExit   = &cbMethodExit; 
           error = (*env)->SetEventCallbacks(env, &callbacks, (jint)sizeof(callbacks));
                //Method Entry
           error = (*env)->SetEventNotificationMode(env, JVMTI_ENABLE,
                           JVMTI_EVENT_METHOD_ENTRY, (jthread)NULL);
                //Method Exit
           error = (*env)->SetEventNotificationMode(env, JVMTI_ENABLE,
                             JVMTI_EVENT_METHOD_EXIT, (jthread)NULL);
           traceOutput = fopen("test_method_out","w");
           return JNI_OK;