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

JVM/TI test ex03t001 fails assertion

    Details

    • Subcomponent:
    • Resolved In Build:
      b08
    • CPU:
      generic
    • OS:
      generic

      Backports

        Description

        The following test:

            nsk/jvmti/scenarios/extension/EX03/ex03t001

        fails the following assertion:

            Internal Error (src/share/vm/prims/jvmtiExport.cpp:1045)
            Error: assert(prev_state == _thread_blocked,"JavaThread should be at safepoint")

        Here is the URL for the oldest failure that I found in nightly:

        http://sqeweb.sfbay.sun.com/nfs/tools/gtee/results/JDK7/NIGHTLY/VM/2010-02-03/GC_Baseline-Xconc/vm/linux-i586/server/mixed/linux-i586_server_mixed_nsk.quick-jvmti.testlist/analysis.html

        Here is a snippet of the stack trace from the hs_err file:

        --------------- T H R E A D ---------------

        Current thread (0x09d41800): VMThread [stack: 0xa9177000,0xa91f8000] [id=21415]

        Stack: [0xa9177000,0xa91f8000], sp=0xa91f6b10, free space=1fea91f6b88k
        Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
        V [libjvm.so+0x99cc55];; _ZN7VMError6reportEP12outputStream+0x13f5
        V [libjvm.so+0x99cee4];; _ZN7VMError14report_and_dieEv+0x194
        V [libjvm.so+0x443e55];; _Z24report_assertion_failurePKciS0_+0x65
        V [libjvm.so+0x6c1e42];; _ZN11JvmtiExport17post_class_unloadEP12klassOopDesc+0x202
        V [libjvm.so+0x49aa7e];; _ZN10Dictionary12do_unloadingEP17BoolObjectClosure+0x12fe
        V [libjvm.so+0x910737];; _ZN16SystemDictionary12do_unloadingEP17BoolObjectClosure+0x27
        V [libjvm.so+0x427805];; _ZN12CMSCollector17refProcessingWorkEbb+0x405
        V [libjvm.so+0x427d4f];; _ZN12CMSCollector24checkpointRootsFinalWorkEbbb+0x28f
        V [libjvm.so+0x4283fb];; _ZN12CMSCollector20checkpointRootsFinalEbbb+0x10b
        V [libjvm.so+0x42874c];; _ZN12CMSCollector16do_CMS_operationENS_11CMS_op_typeE+0x1cc
        V [libjvm.so+0x99acdf];; _ZN19VM_CMS_Final_Remark4doitEv+0xff
        V [libjvm.so+0x9ba9e2];; _ZN12VM_Operation8evaluateEv+0x82
        V [libjvm.so+0x9b85f2];; _ZN8VMThread18evaluate_operationEP12VM_Operation+0xb2
        V [libjvm.so+0x9b8f90];; _ZN8VMThread4loopEv+0x210
        V [libjvm.so+0x9b952d];; _ZN8VMThread3runEv+0xbd
        V [libjvm.so+0x7f0f49];; _ZL10java_startP6Thread+0xf9
        C [libpthread.so.0+0x55e2]

        VM_Operation (0xa9493298): CMS_Final_Remark, mode: safepoint, requested by thread 0x09cf5400
        Here is the URL for a Solaris X86 instance of this failure:

        http://sqeweb.sfbay.sun.com/nfs/tools/gtee/results/JDK7/NIGHTLY/VM/2010-02-10/GC_Baseline-Xinc/vm/solaris-i586/server/mixed/solaris-i586_server_mixed_nsk.quick-jvmti.testlist/analysis.html

        Here is the URL for a Linux AMD64 instance of this failure:

        http://sqeweb.sfbay.sun.com/nfs/tools/gtee/results/JDK7/NIGHTLY/VM/2010-02-11/GC_Baseline-Xinc/vm/linux-amd64/server/mixed/linux-amd64_server_mixed_nsk.quick-jvmti.testlist/analysis.html

        While nightly doesn't show any Solaris SPARC or Windows failures,
        I don't see any reason that this failure mode should be specific
        to Linux X86, Linux AMD64 or Solaris X86.
        Test name and assertion for DKFL
        nsk/jvmti/scenarios/extension/EX03/ex03t001

        ;; Using jvm: "/export/local/common/jdk/baseline/solaris-sparc/jre/lib/sparc/client/libjvm.so"
        #
        # A fatal error has been detected by the Java Runtime Environment:
        #
        # Internal Error (/tmp/jprt/P1/B/080317.jc234399/source/src/share/vm/prims/jvmtiExport.cpp:994), pid=20048, tid=6
        # assert(prev_state == _thread_blocked) failed: JavaThread should be at safepoint
        #
        # JRE version: 7.0-b141
        # Java VM: Java HotSpot(TM) Client VM (21.0-b12-internal-201105170803.jc234399.7041440_fix-fastdebug mixed mode solaris-sparc )
        # Core dump written. Default location: /export/local/50462.JDK7.NIGHTLY.VM+solaris-sparc_vm_client_mixed_nsk.quick-jvmti.testlist/results/ResultDir/ex03t001/core or core.20048
        #
        # If you would like to submit a bug report, please visit:
        # http://bugreport.sun.com/bugreport/crash.jsp
        #

          Issue Links

            Activity

            Hide
            sspitsyn Serguei Spitsyn added a comment - - edited
            I tried to prototype the approach suggested by Dan and discovered a couple of complications.
            Not very sure my conclusions are exactly right, so, please, correct me if needed.

            1. First complication is that class unload even callback has a jclass argument referring the class which is about to be unloaded and GC-ed.
                Some mechanism is needed to ensure the class is alive up to the point of the callback invocation.
                It is not easy to provide this if the class unload events are handled on the ServiceThread.

            2. Second complication is that the initial naked Klass* pointer can be potentially redirected (not sure if the CLDs are moved around).
                I do not know a good way to create a global handle object when the VM_operation is executed.
                It looks like a good way to provide safety in this case could be to register an oops_do().

            Side note:
               My rough ServiceThread-based prototype behaves well in terms that the test is always passed and no crashes observed.
               But I'm still in doubt that it is safe as it can be just luckily passed by accessing the deleted CLD data.
               The internal webrev link (temporary purposes):
                  http://javaweb.sfbay.sun.com/java/svc/ss45998/webrevs/2014/hotspot/6976636-JVMTI-unload-proto/
            Show
            sspitsyn Serguei Spitsyn added a comment - - edited I tried to prototype the approach suggested by Dan and discovered a couple of complications. Not very sure my conclusions are exactly right, so, please, correct me if needed. 1. First complication is that class unload even callback has a jclass argument referring the class which is about to be unloaded and GC-ed.     Some mechanism is needed to ensure the class is alive up to the point of the callback invocation.     It is not easy to provide this if the class unload events are handled on the ServiceThread. 2. Second complication is that the initial naked Klass* pointer can be potentially redirected (not sure if the CLDs are moved around).     I do not know a good way to create a global handle object when the VM_operation is executed.     It looks like a good way to provide safety in this case could be to register an oops_do(). Side note:    My rough ServiceThread-based prototype behaves well in terms that the test is always passed and no crashes observed.    But I'm still in doubt that it is safe as it can be just luckily passed by accessing the deleted CLD data.    The internal webrev link (temporary purposes):        http://javaweb.sfbay.sun.com/java/svc/ss45998/webrevs/2014/hotspot/6976636-JVMTI-unload-proto/
            Hide
            dcubed Daniel Daugherty added a comment -
            I'm failure certain that EXT_EVENT_CLASS_UNLOAD is a post action event.
            In other words, the event is posted after the class has been unloaded. The
            jclass value can simply be used to update an internal mapping list in the
            agent. It cannot be used for normal operations that would work on a live
            jclass.
            Show
            dcubed Daniel Daugherty added a comment - I'm failure certain that EXT_EVENT_CLASS_UNLOAD is a post action event. In other words, the event is posted after the class has been unloaded. The jclass value can simply be used to update an internal mapping list in the agent. It cannot be used for normal operations that would work on a live jclass.
            Hide
            sspitsyn Serguei Spitsyn added a comment -
            To Dan:

            I think, the class unload event needs to be handled before the class has been really unloaded.
            (unfortunately, I did not find any details on that in the old JVMDI spec)

            There are two issues with the class that has been unloaded:

            1. If class is not alive then the jclass argument is useless.
                The jclass must be a JNI local reference which is a thread local handle (see the JNIHandles::make_local()).
                Such references have different addresses and can not be directly used for bookkeeping purposes.
                At least, the ability to get the class name out of the jclass is required.

            2. There is even no way to provide such a local reference for the event handler.
                A class object (or a handle) is needed to create a JNI local reference:
                  - JNIHandles::make_local(Thread* thread, oop obj)
                  - JNIHandles::make_local(JNIEnv* env, oop obj)

            So that now I'm puzzled with the question how to implement this correctly.
            Show
            sspitsyn Serguei Spitsyn added a comment - To Dan: I think, the class unload event needs to be handled before the class has been really unloaded. (unfortunately, I did not find any details on that in the old JVMDI spec) There are two issues with the class that has been unloaded: 1. If class is not alive then the jclass argument is useless.     The jclass must be a JNI local reference which is a thread local handle (see the JNIHandles::make_local()).     Such references have different addresses and can not be directly used for bookkeeping purposes.     At least, the ability to get the class name out of the jclass is required. 2. There is even no way to provide such a local reference for the event handler.     A class object (or a handle) is needed to create a JNI local reference:       - JNIHandles::make_local(Thread* thread, oop obj)       - JNIHandles::make_local(JNIEnv* env, oop obj) So that now I'm puzzled with the question how to implement this correctly.
            Hide
            sspitsyn Serguei Spitsyn added a comment - - edited
            It looks like the jthread argument is not really needed in the class unload event callback.

            The jthread was specified in the JVMDI as follows:

            Class Events (JVMDI_EVENT_CLASS_LOAD, JVMDI_EVENT_CLASS_UNLOAD, JVMDI_EVENT_CLASS_PREPARE)
                    typedef struct {
                        jthread thread;
                        jclass clazz;
                    } JVMDI_class_event_data;

            My guess is that the "jclass clazz" was needed for two other events:
              JVMDI_EVENT_CLASS_LOAD, JVMDI_EVENT_CLASS_PREPARE

            I'm suggesting to remove it from the arguments list.

            The JDWP agent does not use the class unload events.
            It generates synthetic events for JDI basing on the absence of the classes in the table of currently loaded classes.
            So that the JPDA does not depend on the EXT_EVENT_CLASS_UNLOAD debug extension.
            And both JDI and JDWP do not pass the jthread argument to the event handlers.

            The only internal dependency is the VM SQE test ex03t001.
            I have a doubt we have more tests like this.

            More detailed suggestion is:
              1. Remove this thread state check from the JvmtiExport::post_class_unload().
                  With the removed check this event from the CMS will be posted with the jthread argument equal to NULL.
              2. Fix the VM SQE test nsk/jvmti/scenarios/extension/EX03/ex03t001 to totally ignore the thread argument.

            Another approach to consider is to totally remove the jclass parameter from the event callback.
            But I do not see it yet as an important thing to do.

            Show
            sspitsyn Serguei Spitsyn added a comment - - edited It looks like the jthread argument is not really needed in the class unload event callback. The jthread was specified in the JVMDI as follows: Class Events (JVMDI_EVENT_CLASS_LOAD, JVMDI_EVENT_CLASS_UNLOAD, JVMDI_EVENT_CLASS_PREPARE)         typedef struct {             jthread thread;             jclass clazz;         } JVMDI_class_event_data; My guess is that the "jclass clazz" was needed for two other events:   JVMDI_EVENT_CLASS_LOAD, JVMDI_EVENT_CLASS_PREPARE I'm suggesting to remove it from the arguments list. The JDWP agent does not use the class unload events. It generates synthetic events for JDI basing on the absence of the classes in the table of currently loaded classes. So that the JPDA does not depend on the EXT_EVENT_CLASS_UNLOAD debug extension. And both JDI and JDWP do not pass the jthread argument to the event handlers. The only internal dependency is the VM SQE test ex03t001. I have a doubt we have more tests like this. More detailed suggestion is:   1. Remove this thread state check from the JvmtiExport::post_class_unload().       With the removed check this event from the CMS will be posted with the jthread argument equal to NULL.   2. Fix the VM SQE test nsk/jvmti/scenarios/extension/EX03/ex03t001 to totally ignore the thread argument. Another approach to consider is to totally remove the jclass parameter from the event callback. But I do not see it yet as an important thing to do.
            Hide
            sspitsyn Serguei Spitsyn added a comment -
            The suggested fix is:

            diff -r 7380034e5b31 src/share/vm/prims/jvmtiExport.cpp
            --- a/src/share/vm/prims/jvmtiExport.cpp Mon Mar 03 13:58:52 2014 -0500
            +++ b/src/share/vm/prims/jvmtiExport.cpp Thu Mar 13 06:21:45 2014 -0700
            @@ -993,7 +993,9 @@ void JvmtiExport::post_class_unload(Klas
                     // Before we call the JVMTI agent, we have to set the state in the
                     // thread for which we are proxying.
                     JavaThreadState prev_state = real_thread->thread_state();
            - assert(prev_state == _thread_blocked, "JavaThread should be at safepoint");
            + assert(((Thread *)real_thread)->is_ConcurrentGC_thread() ||
            + (real_thread->is_Java_thread() && prev_state == _thread_blocked),
            + "should be ConcurrentGCThread or JavaThread at safepoint");
                     real_thread->set_thread_state(_thread_in_native);
             
                     jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload;
            Show
            sspitsyn Serguei Spitsyn added a comment - The suggested fix is: diff -r 7380034e5b31 src/share/vm/prims/jvmtiExport.cpp --- a/src/share/vm/prims/jvmtiExport.cpp Mon Mar 03 13:58:52 2014 -0500 +++ b/src/share/vm/prims/jvmtiExport.cpp Thu Mar 13 06:21:45 2014 -0700 @@ -993,7 +993,9 @@ void JvmtiExport::post_class_unload(Klas          // Before we call the JVMTI agent, we have to set the state in the          // thread for which we are proxying.          JavaThreadState prev_state = real_thread->thread_state(); - assert(prev_state == _thread_blocked, "JavaThread should be at safepoint"); + assert(((Thread *)real_thread)->is_ConcurrentGC_thread() || + (real_thread->is_Java_thread() && prev_state == _thread_blocked), + "should be ConcurrentGCThread or JavaThread at safepoint");          real_thread->set_thread_state(_thread_in_native);            jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload;
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/rev/d9c2726a4960
            User: sspitsyn
            Date: 2014-03-18 01:04:00 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/hs-rt/hotspot/rev/d9c2726a4960 User: sspitsyn Date: 2014-03-18 01:04:00 +0000
            Hide
            hgupdate HG Updates added a comment -
            URL: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/d9c2726a4960
            User: lana
            Date: 2014-04-09 18:28:01 +0000
            Show
            hgupdate HG Updates added a comment - URL: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/d9c2726a4960 User: lana Date: 2014-04-09 18:28:01 +0000

              People

              • Assignee:
                sspitsyn Serguei Spitsyn
                Reporter:
                dcubed Daniel Daugherty
              • Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: