@@ -1278,6 +1278,7 @@ class GetThreadSnapshotHandshakeClosure: public HandshakeClosure {
1278
1278
if (is_virtual) {
1279
1279
// mounted vthread, use carrier thread state
1280
1280
oop carrier_thread = java_lang_VirtualThread::carrier_thread (_thread_h ());
1281
+ assert (carrier_thread != nullptr , " should only get here for a mounted vthread" );
1281
1282
_thread_status = java_lang_Thread::get_thread_status (carrier_thread);
1282
1283
} else {
1283
1284
_thread_status = java_lang_Thread::get_thread_status (_thread_h ());
@@ -1477,7 +1478,17 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
1477
1478
1478
1479
carrier_thread = Handle (THREAD, java_lang_VirtualThread::carrier_thread (thread_h ()));
1479
1480
if (carrier_thread != nullptr ) {
1481
+ // Note: The java_thread associated with this carrier_thread may not be
1482
+ // protected by the ThreadsListHandle above. There could have been an
1483
+ // unmount and remount after the ThreadsListHandle above was created
1484
+ // and before the JvmtiVTMSTransitionDisabler was created. However, as
1485
+ // we have disabled transitions, if we are mounted on it, then it cannot
1486
+ // terminate and so is safe to handshake with.
1480
1487
java_thread = java_lang_Thread::thread (carrier_thread ());
1488
+ } else {
1489
+ // We may have previously found a carrier but the virtual thread has unmounted
1490
+ // after that, so clear that previous reference.
1491
+ java_thread = nullptr ;
1481
1492
}
1482
1493
} else {
1483
1494
java_thread = java_lang_Thread::thread (thread_h ());
@@ -1554,4 +1565,3 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
1554
1565
}
1555
1566
1556
1567
#endif // INCLUDE_JVMTI
1557
-
0 commit comments