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

DisposeEnvironment doesn't relinquish capabilities held by env

XMLWordPrintable

    • tiger
    • sparc
    • solaris_8
    • Verified



      Name: vsR10008 Date: 09/10/2003



      JVMTI spec says:

      "Dispose Environment

      jvmtiError
      DisposeEnvironment(jvmtiEnv* env)

      Shutdown a JVMTI connection created with JNI GetEnv (see JVMTI Environments).
      Dispose of any resources held by the environment."

      According to spec capabilities set is one of resources held by environment:

      "JVMTI Environments

      The JVMTI specification supports the use of multiple simultaneous JVMTI agents.
      Each agent has its own JVMTI environment. That is, the JVMTI state is separate
      for each agent - changes to one environment do not affect the others. The state
      of a JVMTI environment includes:

           * the event callbacks
           * the set of events which are enabled
           * the capabilities
           * the memory allocation/deallocation hooks"

      Therefore invocation of DisposeEnvironment should relinquish all the capabilities
      the specified environment currently possesses.

      The current RI doesn't dispose enviromnent properly. To reproduce bug please run
      the following shell script (do not forget to change the definition of JDK_PATH
      in the first line):

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

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

      echo "...creating a.c"
      cat - > a.c <<EOF
      #include <stdio.h>
      #include "jvmti.h"

      #define BAD_CODE

      static jvmtiEnv *jvmti = NULL;
      jvmtiCapabilities pcapa;
      jvmtiCapabilities capa;
      jvmtiCapabilities capa1;
      JavaVM *global_jvm;

      JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
             printf("Loaded!\n");
             global_jvm = jvm;
             return JNI_OK;
      }

      JNIEXPORT void JNICALL
      Java_a_check(JNIEnv *env, jclass cls) {
             jvmtiError err;
             jint res;

             res = (*global_jvm)->GetEnv(global_jvm, (void **) &jvmti, JVMTI_VERSION_1_0);
             memset(&capa, 0, sizeof(jvmtiCapabilities));
             capa.can_tag_objects = 1;
             err=(*jvmti)->AddCapabilities(jvmti, &capa);
             if(err != JVMTI_ERROR_NONE) {
                 printf("Could not add capability.\n");
                 return;
             }
      #ifdef WORKAROUND
             err=(*jvmti)->RelinquishCapabilities(jvmti, &capa);
             if(err != JVMTI_ERROR_NONE) {
                 printf("Could not relinquish capability.\n");
                 return;
             }
      #endif
             printf("Disposing JVMTI environment...\n");
             err=(*jvmti)->DisposeEnvironment(jvmti);
             if(err != JVMTI_ERROR_NONE) {
                 printf("Could not dispose env.\n");
                 return;
             }

             printf("Creating new JVMTI environment...\n");
             res = (*global_jvm)->GetEnv(global_jvm, (void **) &jvmti, JVMTI_VERSION_1_0);
             err=(*jvmti)->AddCapabilities(jvmti, &capa);
             if(err != JVMTI_ERROR_NONE) {
                 printf("*********************************\n");
                 printf("*** Could not add capability. ***\n");
                 printf("*********************************\n");
                 return;
             }
             printf("Finished!\n");
      }

      EOF

      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 "...creating a.java"

      cat - > a.java <<EOF
      public class a {
             native static void check();
             public static void main(String[] args) {
                 System.loadLibrary("a");
                 check();
             }
      }
      EOF

      echo "...creating a.class"

      ${JDK_PATH}/bin/javac -d . a.java

      echo "...running a.class"
      LD_LIBRARY_PATH=. CLASSPATH=. ${JDK_PATH}/bin/java -showversion -agentlib:a a

      echo "...creating WORKAROUND version of liba.so"
      ${CC} -G -KPIC -o liba.so -I${JDK_PATH}/include -I${JDK_PATH}/include/solaris -I${JVMTI_H_PATH} -DWORKAROUND a.c

      echo "...running a.class with workaround"
      LD_LIBRARY_PATH=. CLASSPATH=. ${JDK_PATH}/bin/java -agentlib:a a

      --- End of file: runme.sh ----------------------------------------------------

      The output is:

      ---------------------------------------------------------------------------
      ...creating a.c
      ...creating liba.so
      ...creating a.java
      ...creating a.class
      ...running a.class
      Loaded!
      java version "1.5.0-beta"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b18)
      Java HotSpot(TM) Client VM (build 1.5.0-beta-b18, mixed mode)

      Disposing JVMTI environment...
      Creating new JVMTI environment...
      *********************************
      *** Could not add capability. ***
      *********************************

      ...creating WORKAROUND version of liba.so
      ...running a.class with workaround
      Loaded!
      Disposing JVMTI environment...
      Creating new JVMTI environment...
      Finished!
      ---------------------------------------------------------------------------


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

            swamyv Swamy Venkataramanappa
            atwosunw A2 A2 (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: