2 Replies Latest reply: Jan 31, 2010 4:48 PM by 843810 RSS

    METHOD_ENTRY and METHOD_EXIT events out of order?

    843810
      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);
                      
              
               
           setCapabilities(env);
                        
         
               /*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;                    
      }