When does MONITOR_WAITED get thrown?

JC Beyler jcbeyler at google.com
Mon Sep 18 17:45:14 UTC 2017


Hi all,

When looking at the documentation of
https://docs.oracle.com/javase/7/docs/platform/jvmti/jvmti.html#MonitorWaited
, I see the following description:
"Sent when a thread finishes waiting on an object."

However, there seems to be a slight issue when the MONITOR_WAIT event
handler throws an exception.

Consider the following code:

A) The monitor wait handler throws

static void JNICALL
monitor_wait(jvmtiEnv* jvmti, JNIEnv *env,
             jthread thread, jobject object, jlong timeout) {
  fprintf(stderr, "Waiting!\n");

  jclass newExcCls = env->FindClass("java/lang/IllegalArgumentException");
  // Unable to find the new exception class, give up.
  if (newExcCls == 0) {
    return;
  }
  env->ThrowNew(newExcCls, "Exception from monitor_wait");
}

B) The monitor waited handler does a printf:
static void JNICALL
monitor_waited(jvmtiEnv* jvmti, JNIEnv *env,
               jthread thread, jobject object, jboolean timed_out) {
  fprintf(stderr, "Waited!\n");
}

B) A second thread that will be asked to wait:
 class SecondThread extends Thread {
  public void run() {
    try {
      Thread.sleep(1);
    } catch(Exception e) {
    }
    System.out.println("Hello from A");
  }
}

C) The main thread with the wait:
class Main extends Thread {
  public static void main(String[] args) {
    SecondThread st = new SecondThread();

    synchronized (st) {
      st.start();

      try {
        st.wait();
      } catch(InterruptedException e) {
        System.out.println("Exception caught!");
      }
    }

    System.out.println("Done");
  }
}

D) If I do this, what happens is that I get:

Waiting!
Waited!
Exception in thread "main" java.lang.IllegalArgumentException: Exception
from monitor_wait
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:502)
at Main.main(Main.java:9)
Hello from A

- As we see, we get the print out from waiting, print out from waited and
then the exception in the waiting.


E) If instead, we do st.wait(-100) in the main method, we get:
Waiting!
Exception in thread "main" java.lang.IllegalArgumentException: Exception
from monitor_wait
at java.lang.Object.wait(Native Method)
at Main.main(Main.java:9)
Hello from A

Notes: the stack is slightly different, the printout waited is no longer
there however

F) If finally, we don't throw in the waiting handler but leave the
st.wait(-100) in place:
Waiting!
Exception in thread "main" java.lang.IllegalArgumentException: timeout
value is negative
at java.lang.Object.wait(Native Method)
at Main.main(Main.java:9)
Hello from A


The question thus becomes: is this normal that there is a slight difference
between D/E/F?

Should we try to fix it to have a single behavior in the three cases, and
if so, which would be the behavior that should be the default?

Let me know if you would like to see a full code to easily replicate, I
gave the big parts but left out the Agent_OnLoad method for example.

Thanks!
Jc
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20170918/38d4a8ee/attachment-0001.html>


More information about the serviceability-dev mailing list