-
Bug
-
Resolution: Fixed
-
P3
-
22
-
b27
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8326477 | 21.0.4-oracle | Stefan Karlsson | P3 | Resolved | Fixed | b01 |
JDK-8328336 | 21.0.4 | Aleksey Shipilev | P3 | Resolved | Fixed | b01 |
This can be seen by running the CompleteExit test with `-XX:+UseZGC -Xmx12m` and the following changes:
```
diff --git a/test/hotspot/jtreg/runtime/Monitor/libCompleteExit.c b/test/hotspot/jtreg/runtime/Monitor/libCompleteExit.c
index 07ba0ff0ef8..fac500542ea 100644
--- a/test/hotspot/jtreg/runtime/Monitor/libCompleteExit.c
+++ b/test/hotspot/jtreg/runtime/Monitor/libCompleteExit.c
@@ -44,8 +44,27 @@ static void* do_test() {
int res = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL);
if (res != JNI_OK) die("AttachCurrentThread");
- if ((*env)->MonitorEnter(env, t1) != 0) die("MonitorEnter");
- if ((*env)->MonitorEnter(env, t2) != 0) die("MonitorEnter");
+ jclass c = (*env)->FindClass(env, "java/lang/Object");
+ if (c == 0) {
+ die("No class");
+ }
+
+ jmethodID m = (*env)->GetMethodID(env, c, "<init>", "()V");
+ if (m == 0) {
+ die("No constructor");
+ }
+
+ jobject o1 = (*env)->NewObject(env, c, m);
+ jobject o2 = (*env)->NewObject(env, c, m);
+ jobject o3 = (*env)->NewObject(env, c, m);
+
+ if ((*env)->MonitorEnter(env, o1) != 0) die("MonitorEnter");
+ if ((*env)->MonitorEnter(env, o2) != 0) die("MonitorEnter");
+
+ (*env)->DeleteLocalRef(env, o1);
+ (*env)->DeleteLocalRef(env, o2);
+
+ (*env)->NewObjectArray(env, 1024 * 1024, c, o3);
if ((*jvm)->DetachCurrentThread(jvm) != JNI_OK) die("DetachCurrentThread");
pthread_exit(NULL);
```
The assert comes from this path:
V [libjvm.so+0x171fb1d] ObjectSynchronizer::owned_monitors_iterate(MonitorClosure*, JavaThread*)+0x15d (synchronizer.cpp:1094)
V [libjvm.so+0x1720d2a] ObjectSynchronizer::release_monitors_owned_by_thread(JavaThread*)+0x4a (synchronizer.cpp:1792)
V [libjvm.so+0xeb806c] JavaThread::exit(bool, JavaThread::ExitType)+0x7fc (javaThread.cpp:871)
V [libjvm.so+0xf8066a] jni_DetachCurrentThread+0xda (jni.cpp:3923)
C [libCompleteExit.so+0xb53] do_test+0x173 (libCompleteExit.c:73)
I've also managed to reproduce this issue from VM_ThreadDump with this patch:
```
diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp
index ed323b7a416..7bf8091a4e6 100644
--- a/src/hotspot/share/runtime/synchronizer.cpp
+++ b/src/hotspot/share/runtime/synchronizer.cpp
@@ -1091,7 +1091,7 @@ void ObjectSynchronizer::owned_monitors_iterate_filtered(MonitorClosure* closure
// ObjectMonitor cannot be async deflated.
if (monitor->has_owner() && filter(monitor->owner_raw())) {
assert(!monitor->is_being_async_deflated(), "Owned monitors should not be deflating");
- assert(monitor->object_peek() != nullptr, "Owned monitors should not have a dead object");
+ assert(UseNewCode || monitor->object_peek() != nullptr, "Owned monitors should not have a dead object");
closure->do_monitor(monitor);
}
diff --git a/test/hotspot/jtreg/runtime/Monitor/CompleteExit.java b/test/hotspot/jtreg/runtime/Monitor/CompleteExit.java
index 7e63050dc9e..11b6149978d 100644
--- a/test/hotspot/jtreg/runtime/Monitor/CompleteExit.java
+++ b/test/hotspot/jtreg/runtime/Monitor/CompleteExit.java
@@ -31,6 +31,9 @@
* @run main/native CompleteExit
*/
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
+
public class CompleteExit {
public static native void testIt(Object o1, Object o2);
@@ -41,7 +44,21 @@ public class CompleteExit {
System.loadLibrary("CompleteExit");
}
+ static private void dumpThreads() {
+ ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
+ while (true) {
+ threadBean.dumpAllThreads(true, false);
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {}
+ }
+ }
+
public static void main(String[] args) throws Exception {
+ Thread threadDumper = new Thread(() -> dumpThreads());
+ threadDumper.setDaemon(true);
+ threadDumper.start();
+
testIt(o1, o2);
}
}
diff --git a/test/hotspot/jtreg/runtime/Monitor/libCompleteExit.c b/test/hotspot/jtreg/runtime/Monitor/libCompleteExit.c
index 07ba0ff0ef8..6b1a5465b2e 100644
--- a/test/hotspot/jtreg/runtime/Monitor/libCompleteExit.c
+++ b/test/hotspot/jtreg/runtime/Monitor/libCompleteExit.c
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
+#include <unistd.h>
#define die(x) do { printf("%s:%s\n",x , __func__); perror(x); exit(EXIT_FAILURE); } while (0)
@@ -44,8 +45,30 @@ static void* do_test() {
int res = (*jvm)->AttachCurrentThread(jvm, (void**)&env, NULL);
if (res != JNI_OK) die("AttachCurrentThread");
- if ((*env)->MonitorEnter(env, t1) != 0) die("MonitorEnter");
- if ((*env)->MonitorEnter(env, t2) != 0) die("MonitorEnter");
+ jclass c = (*env)->FindClass(env, "java/lang/Object");
+ if (c == 0) {
+ die("No class");
+ }
+
+ jmethodID m = (*env)->GetMethodID(env, c, "<init>", "()V");
+ if (m == 0) {
+ die("No constructor");
+ }
+
+ jobject o1 = (*env)->NewObject(env, c, m);
+ jobject o2 = (*env)->NewObject(env, c, m);
+ jobject o3 = (*env)->NewObject(env, c, m);
+
+ if ((*env)->MonitorEnter(env, o1) != 0) die("MonitorEnter");
+ if ((*env)->MonitorEnter(env, o2) != 0) die("MonitorEnter");
+
+ (*env)->DeleteLocalRef(env, o1);
+ (*env)->DeleteLocalRef(env, o2);
+
+ (*env)->NewObjectArray(env, 1024 * 1024, c, o3);
+ printf("Going to sleep: 10s");
+ sleep(10);
+ printf("Slept");
if ((*jvm)->DetachCurrentThread(jvm) != JNI_OK) die("DetachCurrentThread");
pthread_exit(NULL);
```
- backported by
-
JDK-8326477 assert(monitor->object_peek() != nullptr) failed: Owned monitors should not have a dead object
- Resolved
-
JDK-8328336 assert(monitor->object_peek() != nullptr) failed: Owned monitors should not have a dead object
- Resolved
- relates to
-
JDK-8320561 Inconsistency in monitorinflation logging
- Resolved
-
JDK-8318757 VM_ThreadDump asserts in interleaved ObjectMonitor::deflate_monitor calls
- Closed
-
JDK-8320720 JNI Locked Monitors can be associated with a dead (null) object
- Open
-
JDK-8320721 JVMTI GetOwnedMonitorInfo needs to be aware that JNI Locked Monitors can be associated with a dead (null) object
- Open
-
JDK-8322743 C2: prevent lock region elimination in OSR compilation
- Resolved
- links to
-
Commit openjdk/jdk21u-dev/d1af31b6
-
Commit openjdk/jdk/0d146361
-
Review openjdk/jdk21u-dev/337
-
Review openjdk/jdk/16783