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

JVMTI: Class initialization generates MonitorWaited without matched MonitorWait

    XMLWordPrintable

Details

    • Bug
    • Status: Open
    • P4
    • Resolution: Unresolved
    • 8u40, 9
    • tbd
    • hotspot
    • None
    • generic
    • generic

    Description

      When JVM waits on a class loading lock, JVMTI_EVENT_MONITOR_WAITED is posted, but the corresponding JVMTI_EVENT_MONITOR_WAIT is not.

      Though JVMTI Spec does not strictly prescribe when these events should occur (see JDK-6455295), the common sense suggests that whenever an object waiting happens either both events should be posted or none at all.

      Here is an example to demonstrate the issue:
      (java -agentlib:monitorWaitAgent MonitorWait)

      // MonitorWait.java
      public class MonitorWait {
          
          public static void main(String[] args) {
              new Thread(Parent::new).start();
              new Child();
          }
       
          static class Parent {
              static {
                  try {
                      Thread.sleep(200);
                  } catch (Exception e) { /* ignore */ }
              }
          }

          static class Child extends Parent {
          }
      }

      // monitorWaitAgent.c
      #include <jvmti.h>
      #include <string.h>
      #include <stdio.h>

      void JNICALL MonitorWait(jvmtiEnv* jvmti, JNIEnv* env, jthread thread, jobject object, jlong timeout) {
          printf("> MonitorWait\n");
      }

      void JNICALL MonitorWaited(jvmtiEnv* jvmti, JNIEnv* env, jthread thread, jobject object, jboolean timed_out) {
          printf("< MonitorWaited\n");
      }

      JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
          jvmtiEnv* jvmti;
          jvmtiEventCallbacks callbacks;
          jvmtiCapabilities capabilities;

          (*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_2);

          memset(&capabilities, 0, sizeof(capabilities));
          capabilities.can_generate_monitor_events = 1;
          (*jvmti)->AddCapabilities(jvmti, &capabilities);

          memset(&callbacks, 0, sizeof(callbacks));
          callbacks.MonitorWait = MonitorWait;
          callbacks.MonitorWaited = MonitorWaited;
          (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
          (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAIT, NULL);
          (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAITED, NULL);
          
          printf("Agent loaded\n");
          return 0;
      }

      Attachments

        Issue Links

          Activity

            People

              sspitsyn Serguei Spitsyn
              apangin Andrei Pangin
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated: