Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4959450

MethodEnter notification unsetting corrupts JVMTI

XMLWordPrintable

    • b37
    • generic
    • generic
    • Verified



      Name: vsR10008 Date: 11/25/2003


      JVMTI spec allows multiple environments to be used: each time
      we call GetEnv we will get new fresh environment. Spec says:
      "Each environment has its own state (for example, desired events, event handling
      functions, and capabilities)".

      The following test shows that setting notification for MethodEntry off
      may corrupt curent or subsequent environments. This occurs when following
      conditions are true:
      1. Consequent environment is created in separate Java thread;
      2. Notification are off before environment disposal.

      To reproduce this bug please run on Solaris the following sh script
      (do not forget to change JDK_PATH var). You can specify the number
      of iterations as script's parameter - note, that faster system will
      require greater number of iteration to reproduce the bug (I think 10000
      iteration will be OK in any case)

      ---- File: runme.sh ---------------------------------------------------
      JDK_PATH="/java/re/jdk/1.5.0/latest/binaries/solaris-sparc"

      RUNS=${1:-100}

      CC="cc"
      JVMTI_H_PATH="${JDK_PATH}/include"

      echo "...creating a.c"
      cat - > a.c <<EOF

      #include <stdio.h>
      #include "jvmti.h"

      static jvmtiEnv *jvmti = NULL;
      static jvmtiEventCallbacks callbacks;
      static JavaVM *jvm = NULL;

      JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm0, char *options, void *reserved) {
          jvm = jvm0;
          return JNI_OK;
      }

      void JNICALL
      MethodEntry(jvmtiEnv *jvmti_env,
                  JNIEnv* jni_env,
                  jthread thread,
                  jmethodID method) {
      }

      JNIEXPORT int JNICALL
      Java_a_check(JNIEnv *env, jclass cls) {
          int res;

          if (jvmti != NULL) {
           (*jvmti)->DisposeEnvironment(jvmti);
          }

          res = (*jvm)->GetEnv(jvm, (void **) &jvmti,
                JVMTI_VERSION_1_0);

          callbacks.MethodEntry = &MethodEntry;

          (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));

          (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
                                              JVMTI_EVENT_METHOD_ENTRY, NULL);
      }


      JNIEXPORT void JNICALL
      Java_a_cleanup(JNIEnv *env, jclass cls) {

      #ifdef CLEANUP
          (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_DISABLE,
                                                   JVMTI_EVENT_METHOD_ENTRY, NULL);
      #endif

      }
      EOF

      echo "...creating a.java"
      cat - > a.java <<EOF
      public class a {
          native static void check();
          native static void cleanup();

          public static void main(String args[]) {
              System.loadLibrary("a");
              for(int i=0;i<${RUNS};i++) {
                  System.out.println("#"+i);
                  Runner run = new Runner();
                  run.start();
                  try {
               run.join();
                  } catch (Throwable t) {
                  }
              }
          }
          public static void target() {
          }
      }

      class Runner extends Thread {
      public void run() {
      a.check();
      a.target();
      a.cleanup();
      }
      }
      EOF
      echo "...creating a.class"
      ${JDK_PATH}/bin/javac -d . a.java

      echo "--- SHOULD PASS ----"
      echo "...creating liba.so"
      ${CC} -G -KPIC -o liba.so -I${JDK_PATH}/include -I${JDK_PATH}/include/solaris -I${JVMTI_H_PATH} a.c
      echo "...running a.class"
      LD_LIBRARY_PATH=. CLASSPATH=. ${JDK_PATH}/bin/java -showversion -agentlib:a a > log1
      if [ "$?" != "0" ]; then
      echo "************ UNEXPECTED FAILURE ************"
      tail log1
      fi

      echo "--- SHOULD FAIL: CLEANUP ----"
      echo "...creating liba.so"
      ${CC} -G -KPIC -o liba.so -DCLEANUP -I${JDK_PATH}/include -I${JDK_PATH}/include/solaris -I${JVMTI_H_PATH} a.c
      echo "...running a.class"
      LD_LIBRARY_PATH=. CLASSPATH=. ${JDK_PATH}/bin/java -showversion -agentlib:a a > log2
      if [ "$?" != "0" ]; then
      echo "----------- EXPECTED FAILURE ------------"
      tail log2
      fi
      -----------------------------------------------------------------------

      The output log of this test is as follows:

      > runme.sh 10000
      runme1.sh 100
      ...creating a.c
      ...creating a.java
      ...creating a.class
      --- SHOULD PASS ----
      ...creating liba.so
      ...running a.class
      java version "1.5.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b28)
      Java HotSpot(TM) Client VM (build 1.5.0-beta-b28, mixed mode)

      --- SHOULD FAIL: CLEANUP ----
      ...creating liba.so
      ...running a.class
      java version "1.5.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b28)
      Java HotSpot(TM) Client VM (build 1.5.0-beta-b28, mixed mode)

      ./runme1.sh: line 109: 14295 Abort (core dumped) LD_LIBRARY_PATH=. CLASSPATH=. ${JDK_PATH}/bin/java -showversion -agentlib:a a >log2
      ----------- EXPECTED FAILURE ------------
      #
      # Java VM: Java HotSpot(TM) Client VM (1.5.0-beta-b28 mixed mode)
      # Problematic frame:
      # V [libjvm.so+0x3c1ef4]
      #
      # An error report file with more information is saved as hs_err_pid14295.log
      #
      # If you would like to submit a bug report, please visit:
      # http://java.sun.com/webapps/bugreport/crash.jsp
      #

      ======================================================================

            alanb Alan Bateman
            atwosunw A2 A2 (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: