On Fri, 3 Jul 2026 00:49:43 GMT, Patricio Chilano Mateo <[email protected]> wrote:
> An asynchronous exception sent by JVMTI `StopThread` to a virtual thread can > be processed and thrown at a point where it is unsafe to do so, leaving the > virtual thread in an invalid state. The unsafe nature of `StopThread` is not > an issue exclusive to virtual threads, but due to extra code executed during > mount/unmount transitions, some tests that are safe for platform threads are > not for virtual threads. In the reported bug, where the async exception is > sent to a thread executing `Thread.yield` in a loop, the exception ends up > being thrown on return from `VirtualThread.startTransition`. Since the > transition bits remain set, the virtual thread hits the reported assert in > `MountUnmountDisabler::start_transition` at the next unmount attempt. > > A similar issue can happen if the exception is thrown right after executing > `VirtualThread.endFirstTransition` or right before > `VirtualThread.startFinalTransition` which can be reproduced by calling > `StopThread` on virtual threads with empty tasks. > > The patch fixes these cases and potentially others that can happen if an > async exception is thrown while executing a method in the `VirtualThread` > class, i.e. it improves the robustness of the implementation in the presence > of async exceptions. It is not an attempt to make `StopThread` bulletproof as > that would be a more ambitious task. > > The proposed changes add two extra checks before installing the asynchronous > exception handshake. The first verifies that the top method is not a > `VirtualThread` method. The second verifies that the exception will be thrown > at the current bytecode, i.e. that exception processing will not be deferred > to a later safepoint poll where the target might already be in one of the > unsafe methods. > > A less restrictive alternative that avoids that second check is to have the > target defer processing of the handshake as long as it’s unsafe to do so (as > based on the first check above). If the handshake is still pending when an > unmount transition begins, we process it and save the exception in the > virtual thread’s `JvmtiThreadState` to be thrown at the end of the next > mount. I have a patch implementing this approach, but the code is a bit more > involved and I wasn’t convinced it was worth it. > > I also refactored `StopThread` by introducing `StopThreadClosure` and > `StopThreadAsyncClosure` handshake classes. This aligns it with the other > JVMTI methods that use `JvmtiHandshake`, and also keeps the `StopThread` > specific logic local to the JVMTI code. > > The changes... test/hotspot/jtreg/vmTestbase/nsk/jdb/kill/kill001/kill001.java line 51: > 49: * @library /vmTestbase > 50: * /test/lib > 51: * @requires test.thread.factory == null Can you elaborate on the need for this? I don't see any mach5 failures of this test for almost a year. ------------- PR Review Comment: https://git.openjdk.org/jdk/pull/31759#discussion_r3517220046
