Name: rmT116609 Date: 11/17/2003
FULL PRODUCT VERSION :
java version "1.4.2_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_02-b03)
Java HotSpot(TM) Client VM (build 1.4.2_02-b03, mixed mode)
FULL OS VERSION :
Microsoft Windows 2000 [Version 5.00.2195]
EXTRA RELEVANT SYSTEM CONFIGURATION :
cygwin version 1.5.5 with gcc version 3.2 20020927
A DESCRIPTION OF THE PROBLEM :
Thread.sleep calls in Java code do not generate JVMPI_EVENT_MONITOR_WAIT or JVMPI_EVENT_MONITOR_WAITED events in a custom JVMPI agent even though the agent has turned on notifications for the same.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Write a simple JVMPI agent (e.g. myagent.c) that turns on notifications for JVMPI_EVENT_MONITOR_WAIT and JVMPI_EVENT_MONITOR_WAITED events. Print out a debug line whenever a JVMPI_EVENT_MONITOR_WAIT or JVMPI_EVENT_MONITOR_WAITED event is caught.
2. compile the C agent code in gcc under cygwin to produce a myagent.dll. Move myagent.dll to $JAVA_HOME/jre/bin directory
2. Write a simple Java program (B.java) that starts a thread which executes Thread.sleep(5000) in an infinite loop. Compile the program.
3. Run B.class with the -Xrunmyagent flag to exercise the JVMPI agent code.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
running: "java -Xrunmyagent B" should produce the following debug output:
initializing...
initialized.
Thread B sleeping
event name = monitor-wait occurred
event name = monitor-waited occurred
Thread B woke up
Thread B sleeping
event name = monitor-wait occurred
event name = monitor-waited occurred
Thread B woke up
... and so on infinite number of times
ACTUAL -
initializing...
initialized.
Thread B sleeping
Thread B woke up
Thread B sleeping
Thread B woke up
... and so on infinite number of times
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
//------------------//
//JVMPI Agent Code: //
//------------------//
#include <jni.h>
#include <jvmpi.h>
// compile line:
// gcc -mno-cygwin -I$JAVA_HOME/include -I$JAVA_HOME/include/win32
// -Wl,--add-stdcall-alias -shared -o myagent.dll myagent.c
JVMPI_Interface *jvmpi_interface;
JavaVM *jvm;
JNIEnv *jni;
// this method prints out name of the event
void process_event (char* name) {
printf ("\nevent name = %s occurred\n", name);
}
void notifyEvent(JVMPI_Event *event) {
switch(event->event_type) {
case JVMPI_EVENT_MONITOR_CONTENDED_ENTER:
process_event ("monitor-contended-enter");
break;
case JVMPI_EVENT_MONITOR_CONTENDED_ENTERED:
process_event ("monitor-contended-entered");
break;
case JVMPI_EVENT_MONITOR_CONTENDED_EXIT:
process_event ("monitor-contended-exit");
break;
case JVMPI_EVENT_MONITOR_WAIT:
process_event ("monitor-wait");
break;
case JVMPI_EVENT_MONITOR_WAITED:
process_event ("monitor-waited");
break;
}
}
JNIEXPORT jint JNICALL JVM_OnLoad(JavaVM *theJvm, char *options,
void *reserved) {
int rc;
jvm = theJvm;
printf("\ninitializing...\n");
rc = (*jvm)->GetEnv (jvm, (void **)&jvmpi_interface, JVMPI_VERSION_1_2);
if (rc < 0) {
fprintf(stderr, "ERROR: rc = %d.\n", rc);
return JNI_ERR;
}
jvmpi_interface->NotifyEvent = notifyEvent;
jvmpi_interface->EnableEvent (JVMPI_EVENT_MONITOR_CONTENDED_ENTER, NULL);
jvmpi_interface->EnableEvent (JVMPI_EVENT_MONITOR_CONTENDED_ENTERED, NULL);
jvmpi_interface->EnableEvent (JVMPI_EVENT_MONITOR_CONTENDED_EXIT, NULL);
jvmpi_interface->EnableEvent (JVMPI_EVENT_MONITOR_WAIT, NULL);
jvmpi_interface->EnableEvent (JVMPI_EVENT_MONITOR_WAITED, NULL);
printf("\ninitialized.\n");
return JNI_OK;
}
/* Java Code */
public class B extends Thread {
public B(String name) {
super(name);
}
public static void main(String[] args) {
B b = new B("Thread B");
b.start();
}
public void run() {
while (true) {
try {
System.out.println(getName() + " sleeping\n");
Thread.sleep(5000, 0);
System.out.println(getName() + " woke up\n");
}
catch (Exception e){}
}
}
}
---------- END SOURCE ----------
(Incident Review ID: 226320)
======================================================================