Skip to content

Commit 92268e1

Browse files
committed
8359870: JVM crashes in AccessInternal::PostRuntimeDispatch
Reviewed-by: alanb, sspitsyn Backport-of: 13a3927
1 parent a98a5e5 commit 92268e1

File tree

5 files changed

+30
-10
lines changed

5 files changed

+30
-10
lines changed

src/hotspot/share/prims/jvm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2966,7 +2966,7 @@ JVM_ENTRY(jobject, JVM_CreateThreadSnapshot(JNIEnv* env, jobject jthread))
29662966
oop snapshot = ThreadSnapshotFactory::get_thread_snapshot(jthread, THREAD);
29672967
return JNIHandles::make_local(THREAD, snapshot);
29682968
#else
2969-
return nullptr;
2969+
THROW_NULL(vmSymbols::java_lang_UnsupportedOperationException());
29702970
#endif
29712971
JVM_END
29722972

src/hotspot/share/services/threadService.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,7 +1439,17 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
14391439

14401440
ResourceMark rm(THREAD);
14411441
HandleMark hm(THREAD);
1442-
Handle thread_h(THREAD, JNIHandles::resolve(jthread));
1442+
1443+
JavaThread* java_thread = nullptr;
1444+
oop thread_oop;
1445+
bool has_javathread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
1446+
assert((has_javathread && thread_oop != nullptr) || !has_javathread, "Missing Thread oop");
1447+
Handle thread_h(THREAD, thread_oop);
1448+
bool is_virtual = java_lang_VirtualThread::is_instance(thread_h()); // Deals with null
1449+
1450+
if (!has_javathread && !is_virtual) {
1451+
return nullptr; // thread terminated so not of interest
1452+
}
14431453

14441454
// wrapper to auto delete JvmtiVTMSTransitionDisabler
14451455
class TransitionDisabler {
@@ -1460,8 +1470,6 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
14601470
}
14611471
} transition_disabler;
14621472

1463-
JavaThread* java_thread = nullptr;
1464-
bool is_virtual = java_lang_VirtualThread::is_instance(thread_h());
14651473
Handle carrier_thread;
14661474
if (is_virtual) {
14671475
// 1st need to disable mount/unmount transitions

src/java.base/share/classes/jdk/internal/vm/ThreadDumper.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,11 @@ private static void dumpThreads(ThreadContainer container, TextWriter writer) {
177177
container.children().forEach(c -> dumpThreads(c, writer));
178178
}
179179

180-
private static void dumpThread(Thread thread, TextWriter writer) {
180+
private static boolean dumpThread(Thread thread, TextWriter writer) {
181181
ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
182+
if (snapshot == null) {
183+
return false; // thread terminated
184+
}
182185
Instant now = Instant.now();
183186
Thread.State state = snapshot.threadState();
184187
writer.println("#" + thread.threadId() + " \"" + snapshot.threadName()
@@ -217,6 +220,7 @@ private static void dumpThread(Thread thread, TextWriter writer) {
217220
depth++;
218221
}
219222
writer.println();
223+
return true;
220224
}
221225

222226
/**
@@ -284,8 +288,9 @@ private static void dumpThreads(ThreadContainer container, JsonWriter jsonWriter
284288
Iterator<Thread> threads = container.threads().iterator();
285289
while (threads.hasNext()) {
286290
Thread thread = threads.next();
287-
dumpThread(thread, jsonWriter);
288-
threadCount++;
291+
if (dumpThread(thread, jsonWriter)) {
292+
threadCount++;
293+
}
289294
}
290295
jsonWriter.endArray(); // threads
291296

@@ -303,11 +308,15 @@ private static void dumpThreads(ThreadContainer container, JsonWriter jsonWriter
303308

304309
/**
305310
* Write a thread to the given JSON writer.
311+
* @return true if the thread dump was written, false otherwise
306312
* @throws UncheckedIOException if an I/O error occurs
307313
*/
308-
private static void dumpThread(Thread thread, JsonWriter jsonWriter) {
314+
private static boolean dumpThread(Thread thread, JsonWriter jsonWriter) {
309315
Instant now = Instant.now();
310316
ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
317+
if (snapshot == null) {
318+
return false; // thread terminated
319+
}
311320
Thread.State state = snapshot.threadState();
312321
StackTraceElement[] stackTrace = snapshot.stackTrace();
313322

@@ -369,6 +378,7 @@ private static void dumpThread(Thread thread, JsonWriter jsonWriter) {
369378
}
370379

371380
jsonWriter.endObject();
381+
return true;
372382
}
373383

374384
/**

src/java.base/share/classes/jdk/internal/vm/ThreadSnapshot.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,14 @@ private ThreadSnapshot() {}
5252

5353
/**
5454
* Take a snapshot of a Thread to get all information about the thread.
55+
* Return null if a ThreadSnapshot is not created, for example if the
56+
* thread has terminated.
5557
* @throws UnsupportedOperationException if not supported by VM
5658
*/
5759
static ThreadSnapshot of(Thread thread) {
5860
ThreadSnapshot snapshot = create(thread);
5961
if (snapshot == null) {
60-
throw new UnsupportedOperationException();
62+
return null; // thread terminated
6163
}
6264
if (snapshot.stackTrace == null) {
6365
snapshot.stackTrace = EMPTY_STACK;

test/jdk/com/sun/management/HotSpotDiagnosticMXBean/DumpThreadsWithEliminatedLock.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,4 +168,4 @@ private static Path genOutputPath(String suffix) throws IOException {
168168
Files.delete(file);
169169
return file;
170170
}
171-
}
171+
}

0 commit comments

Comments
 (0)