8359870: JVM crashes in AccessInternal::PostRuntimeDispatch

Reviewed-by: alanb, sspitsyn
Backport-of: 13a3927855da61fe27f3b43e5e4755d0c5ac5a16
This commit is contained in:
Kevin Walls 2025-07-02 16:59:29 +00:00
parent a98a5e54fc
commit 92268e17be
5 changed files with 30 additions and 10 deletions

View File

@ -2966,7 +2966,7 @@ JVM_ENTRY(jobject, JVM_CreateThreadSnapshot(JNIEnv* env, jobject jthread))
oop snapshot = ThreadSnapshotFactory::get_thread_snapshot(jthread, THREAD);
return JNIHandles::make_local(THREAD, snapshot);
#else
return nullptr;
THROW_NULL(vmSymbols::java_lang_UnsupportedOperationException());
#endif
JVM_END

View File

@ -1439,7 +1439,17 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
ResourceMark rm(THREAD);
HandleMark hm(THREAD);
Handle thread_h(THREAD, JNIHandles::resolve(jthread));
JavaThread* java_thread = nullptr;
oop thread_oop;
bool has_javathread = tlh.cv_internal_thread_to_JavaThread(jthread, &java_thread, &thread_oop);
assert((has_javathread && thread_oop != nullptr) || !has_javathread, "Missing Thread oop");
Handle thread_h(THREAD, thread_oop);
bool is_virtual = java_lang_VirtualThread::is_instance(thread_h()); // Deals with null
if (!has_javathread && !is_virtual) {
return nullptr; // thread terminated so not of interest
}
// wrapper to auto delete JvmtiVTMSTransitionDisabler
class TransitionDisabler {
@ -1460,8 +1470,6 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
}
} transition_disabler;
JavaThread* java_thread = nullptr;
bool is_virtual = java_lang_VirtualThread::is_instance(thread_h());
Handle carrier_thread;
if (is_virtual) {
// 1st need to disable mount/unmount transitions

View File

@ -177,8 +177,11 @@ public class ThreadDumper {
container.children().forEach(c -> dumpThreads(c, writer));
}
private static void dumpThread(Thread thread, TextWriter writer) {
private static boolean dumpThread(Thread thread, TextWriter writer) {
ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
if (snapshot == null) {
return false; // thread terminated
}
Instant now = Instant.now();
Thread.State state = snapshot.threadState();
writer.println("#" + thread.threadId() + " \"" + snapshot.threadName()
@ -217,6 +220,7 @@ public class ThreadDumper {
depth++;
}
writer.println();
return true;
}
/**
@ -284,8 +288,9 @@ public class ThreadDumper {
Iterator<Thread> threads = container.threads().iterator();
while (threads.hasNext()) {
Thread thread = threads.next();
dumpThread(thread, jsonWriter);
threadCount++;
if (dumpThread(thread, jsonWriter)) {
threadCount++;
}
}
jsonWriter.endArray(); // threads
@ -303,11 +308,15 @@ public class ThreadDumper {
/**
* Write a thread to the given JSON writer.
* @return true if the thread dump was written, false otherwise
* @throws UncheckedIOException if an I/O error occurs
*/
private static void dumpThread(Thread thread, JsonWriter jsonWriter) {
private static boolean dumpThread(Thread thread, JsonWriter jsonWriter) {
Instant now = Instant.now();
ThreadSnapshot snapshot = ThreadSnapshot.of(thread);
if (snapshot == null) {
return false; // thread terminated
}
Thread.State state = snapshot.threadState();
StackTraceElement[] stackTrace = snapshot.stackTrace();
@ -369,6 +378,7 @@ public class ThreadDumper {
}
jsonWriter.endObject();
return true;
}
/**

View File

@ -52,12 +52,14 @@ class ThreadSnapshot {
/**
* Take a snapshot of a Thread to get all information about the thread.
* Return null if a ThreadSnapshot is not created, for example if the
* thread has terminated.
* @throws UnsupportedOperationException if not supported by VM
*/
static ThreadSnapshot of(Thread thread) {
ThreadSnapshot snapshot = create(thread);
if (snapshot == null) {
throw new UnsupportedOperationException();
return null; // thread terminated
}
if (snapshot.stackTrace == null) {
snapshot.stackTrace = EMPTY_STACK;

View File

@ -168,4 +168,4 @@ public class DumpThreadsWithEliminatedLock {
Files.delete(file);
return file;
}
}
}