@@ -1278,6 +1278,7 @@ class GetThreadSnapshotHandshakeClosure: public HandshakeClosure {
12781278 if (is_virtual) {
12791279 // mounted vthread, use carrier thread state
12801280 oop carrier_thread = java_lang_VirtualThread::carrier_thread (_thread_h ());
1281+ assert (carrier_thread != nullptr , " should only get here for a mounted vthread" );
12811282 _thread_status = java_lang_Thread::get_thread_status (carrier_thread);
12821283 } else {
12831284 _thread_status = java_lang_Thread::get_thread_status (_thread_h ());
@@ -1477,7 +1478,17 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
14771478
14781479 carrier_thread = Handle (THREAD, java_lang_VirtualThread::carrier_thread (thread_h ()));
14791480 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.
14801487 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 ;
14811492 }
14821493 } else {
14831494 java_thread = java_lang_Thread::thread (thread_h ());
@@ -1554,4 +1565,3 @@ oop ThreadSnapshotFactory::get_thread_snapshot(jobject jthread, TRAPS) {
15541565}
15551566
15561567#endif // INCLUDE_JVMTI
1557-
0 commit comments