The method
`bool SuspendResumeManager::suspend(bool register_vthread_SR) `
has following block for self suspend:
```
if (_target == self) {
// If target is the current thread we can bypass the handshake machinery
// and just suspend directly
ThreadBlockInVM tbivm(self);
MutexLocker ml(_state_lock, Mutex::_no_safepoint_check_flag);
set_suspended(true, register_vthread_SR);
do_owner_suspend();
return true;
}
```
that change state to `_thread_blocked` and then call `set_suspended` which reads `_target->vthread()` handled oop while thread is blocked.
This is prohibited and leading to assertion
`assert(state == _thread_in_vm || state == _thread_in_Java || state == _thread_new) failed: Wrong thread state for accesses: 10`
with stack
```
Stack: [0x0000ffff56768000,0x0000ffff56966000], sp=0x0000ffff569638a0, free space=2030k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x38b0e4] AccessInternal::check_access_thread_state()+0xc0 (accessBackend.cpp:179)
V [libjvm.so+0xece9ac] OopHandle::resolve() const [clone .isra.0]+0x2c (accessBackend.hpp:434)
V [libjvm.so+0xecf120] JavaThread::vthread() const+0x18 (javaThread.cpp:175)
V [libjvm.so+0x17c71ac] SuspendResumeManager::suspend(bool)+0x35c (suspendResumeManager.cpp:74)
V [libjvm.so+0x11cc48c] JvmtiEnvBase::suspend_thread(oop, JavaThread*, bool)+0x1cc (jvmtiEnvBase.cpp:1797)
V [libjvm.so+0x11b31e4] JvmtiEnv::SuspendThread(_jobject*)+0x1d8 (jvmtiEnv.cpp:961)
V [libjvm.so+0x116cc0c] jvmti_SuspendThread+0x1ac (jvmtiEnter.cpp:539)
C [libSuspendResumeAll.so+0x3e88] Java_SuspendResumeAll_TestSuspendResume+0x4e8 (jvmti.h:1884)
j SuspendResumeAll.TestSuspendResume()V+0
j SuspendResumeAll.test_vthreads()I+84
J 10 jdk.internal.vm.Continuation.enterSpecial(Ljdk/internal/vm/Continuation;ZZ)V java.base@26-ea (0 bytes) @ 0x0000ffff801d2234 [0x0000ffff801d2100+0x0000000000000134]
```
The vthread field is used to get thread_id and put it into the list. The thread_id should be calculated before thread is blocked.
Issue might be reproduced with
` make run-test JTREG_TEST_THREAD_FACTORY=Virtual TEST=serviceability/jvmti/vthread/SuspendResumeAll/SuspendResumeAll.java`
However, I am not sure if this combination if going to work even after the fix. It is not executing in CI now.
`bool SuspendResumeManager::suspend(bool register_vthread_SR) `
has following block for self suspend:
```
if (_target == self) {
// If target is the current thread we can bypass the handshake machinery
// and just suspend directly
ThreadBlockInVM tbivm(self);
MutexLocker ml(_state_lock, Mutex::_no_safepoint_check_flag);
set_suspended(true, register_vthread_SR);
do_owner_suspend();
return true;
}
```
that change state to `_thread_blocked` and then call `set_suspended` which reads `_target->vthread()` handled oop while thread is blocked.
This is prohibited and leading to assertion
`assert(state == _thread_in_vm || state == _thread_in_Java || state == _thread_new) failed: Wrong thread state for accesses: 10`
with stack
```
Stack: [0x0000ffff56768000,0x0000ffff56966000], sp=0x0000ffff569638a0, free space=2030k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x38b0e4] AccessInternal::check_access_thread_state()+0xc0 (accessBackend.cpp:179)
V [libjvm.so+0xece9ac] OopHandle::resolve() const [clone .isra.0]+0x2c (accessBackend.hpp:434)
V [libjvm.so+0xecf120] JavaThread::vthread() const+0x18 (javaThread.cpp:175)
V [libjvm.so+0x17c71ac] SuspendResumeManager::suspend(bool)+0x35c (suspendResumeManager.cpp:74)
V [libjvm.so+0x11cc48c] JvmtiEnvBase::suspend_thread(oop, JavaThread*, bool)+0x1cc (jvmtiEnvBase.cpp:1797)
V [libjvm.so+0x11b31e4] JvmtiEnv::SuspendThread(_jobject*)+0x1d8 (jvmtiEnv.cpp:961)
V [libjvm.so+0x116cc0c] jvmti_SuspendThread+0x1ac (jvmtiEnter.cpp:539)
C [libSuspendResumeAll.so+0x3e88] Java_SuspendResumeAll_TestSuspendResume+0x4e8 (jvmti.h:1884)
j SuspendResumeAll.TestSuspendResume()V+0
j SuspendResumeAll.test_vthreads()I+84
J 10 jdk.internal.vm.Continuation.enterSpecial(Ljdk/internal/vm/Continuation;ZZ)V java.base@26-ea (0 bytes) @ 0x0000ffff801d2234 [0x0000ffff801d2100+0x0000000000000134]
```
The vthread field is used to get thread_id and put it into the list. The thread_id should be calculated before thread is blocked.
Issue might be reproduced with
` make run-test JTREG_TEST_THREAD_FACTORY=Virtual TEST=serviceability/jvmti/vthread/SuspendResumeAll/SuspendResumeAll.java`
However, I am not sure if this combination if going to work even after the fix. It is not executing in CI now.
- links to
-
Review(master) openjdk/jdk/27317