Summary
-------
JDWP ThreadReference.Stop and JDI ThreadReference.stop() is updated to support virtual threads.
Problem
-------
JDWP ThreadReference.Stop and JDI ThreadReference.stop() may be used to send an asynchronous exception to a platform thread. They need to be extended to support virtual threads as well. This parallels the support being added to JVMTI StopThread.
Solution
--------
The specs for JDWP ThreadReference.Stop and JDI ThreadReference.stop() are updated so that they can be used to send an asynchronous exception to a virtual thread in some situations.
For JDWP, the error code NOT_IMPLEMENTED is removed. Two new error codes are added instead: THREAD_NOT_SUSPENDED and ERROR_OPAQUE_FRAME.
For JDI, the exception UnsupportedOperationException is removed. OpaqueFrameException is added and IllegalThreadStateException is given an additional meaning.
Specification
-------------
**The JDWP spec includes the following changes below:**
The ThreadReference.Stop command description is updated to replace the following:
The target VM may not support, or may only provide limited support, for
this command when the thread is a virtual thread. It may, for example,
only support this command when the virtual thread is suspended at a
breakpoint or singlestep event.
with:
This command may be used to send an asynchronous
exception to a virtual thread when it is suspended at an event.
An implementation may support sending an asynchronous exception
to a suspended virtual thread in other cases.
The following ThreadReference.Stop error code description is removed:
NOT_IMPLEMENTED: The thread is a virtual thread and the target
VM does not support the command on virtual threads.
The following two ThreadReference.Stop error code descriptions are added:
THREAD_NOT_SUSPENDED:
The thread is a virtual thread and was not suspended.
ERROR_OPAQUE_FRAME:
The thread is a suspended virtual thread and the implementation
was unable to throw an asynchronous exception from the thread's current frame.
The general description of the OPAQUE_FRAME error code is updated to replace the following:
OPAQUE_FRAME 32
Information about the frame is not available (e.g. native frame) or the target VM
is unable to perform an operation on the frame.
with:
OPAQUE_FRAME 32
Information about the frame is not available (e.g. native frame) or the target VM
is unable to perform an operation on the thread's current frame.
**The JDI spec includes the following changes below:**
The ThreadReference.stop() method description is updated to replace the following:
The target VM may not support, or may only provide limited support,
for stopping a virtual thread with an asynchronous exception. It may,
for example, only support this operation when the virtual thread is
suspended at a breakpoint or singlestep event.
with:
This method may be used to send an asynchronous
exception to a virtual thread when it is suspended at an event.
An implementation may support sending an asynchronous exception
to a suspended virtual thread in other cases.
The following ThreadReference.stop() exception description is removed:
* @throws UnsupportedOperationException if the thread is a virtual
* thread and the target VM does not support this operation on
* virtual threads
The following ThreadReference.stop() exception description was modified from:
* @throws IllegalThreadStateException if the thread has terminated
to:
* @throws IllegalThreadStateException if the thread has terminated,
* or if the thread is a virtual thread and was not suspended
The following ThreadReference.stop() exception description is added:
* @throws OpaqueFrameException if the thread is a suspended
* virtual thread and the implementation was unable to throw an
* asynchronous exception from the thread's current frame
**Diff for JDWP spec**
diff --git a/src/java.se/share/data/jdwp/jdwp.spec b/src/java.se/share/data/jdwp/jdwp.spec
index be0bf8d39d13..f788255187c8 100644
--- a/src/java.se/share/data/jdwp/jdwp.spec
+++ b/src/java.se/share/data/jdwp/jdwp.spec
@@ -2004,10 +2004,11 @@ JDWP "Java(tm) Debug Wire Protocol"
(Command Stop=10
"Stops the thread with an asynchronous exception. "
"<p>"
- "The target VM may not support, or may only provide limited support, for "
- "this command when the thread is a virtual thread. It may, for example, "
- "only support this command when the virtual thread is suspended at a "
- "breakpoint or singlestep event."
+ "This command may be used to send an asynchronous "
+ "exception to a virtual thread when it is suspended at an event. "
+ "An implementation may support sending an asynchronous exception "
+ "to a suspended virtual thread in other cases."
+
(Out
(threadObject thread "The thread object ID. ")
(object throwable "Asynchronous exception. This object must "
@@ -2018,8 +2019,10 @@ JDWP "Java(tm) Debug Wire Protocol"
(ErrorSet
(Error INVALID_THREAD "The thread is null, not a valid thread, or the thread "
"is not alive.")
- (Error NOT_IMPLEMENTED "The thread is a virtual thread and the target "
- "VM does not support the command on virtual threads.")
+ (Error THREAD_NOT_SUSPENDED "The thread is a virtual thread and was not suspended.")
+ (Error OPAQUE_FRAME "The thread is a suspended virtual thread and the implementation "
+ "was unable to throw an asynchronous exception "
+ "from the thread's current frame.")
(Error INVALID_OBJECT "If thread is not a known ID or the asynchronous "
"exception has been garbage collected.")
(Error VM_DEAD)
@@ -3166,7 +3169,7 @@ JDWP "Java(tm) Debug Wire Protocol"
"call stack.")
(Constant OPAQUE_FRAME =32 "Information about the frame is not available "
"(e.g. native frame) or the target VM is unable "
- "to perform an operation on the frame.")
+ "to perform an operation on the thread's current frame.")
(Constant NOT_CURRENT_FRAME =33 "Operation can only be performed on current frame.")
(Constant TYPE_MISMATCH =34 "The variable is not an appropriate type for "
"the function used.")
**Diff for JDI spec:**
diff --git a/src/jdk.jdi/share/classes/com/sun/jdi/ThreadReference.java b/src/jdk.jdi/share/classes/com/sun/jdi/ThreadReference.java
index a49fe4c547ce..c66805d38f35 100644
--- a/src/jdk.jdi/share/classes/com/sun/jdi/ThreadReference.java
+++ b/src/jdk.jdi/share/classes/com/sun/jdi/ThreadReference.java
@@ -116,18 +116,20 @@ public interface ThreadReference extends ObjectReference {
* A debugger thread in the target VM will stop this thread
* with the given {@link java.lang.Throwable} object.
* <p>
- * The target VM may not support, or may only provide limited support,
- * for stopping a virtual thread with an asynchronous exception. It may,
- * for example, only support this operation when the virtual thread is
- * suspended at a breakpoint or singlestep event.
+ * This method may be used to send an asynchronous
+ * exception to a virtual thread when it is suspended at an event.
+ * An implementation may support sending an asynchronous exception
+ * to a suspended virtual thread in other cases.
+
*
* @param throwable the asynchronous exception to throw
* @throws InvalidTypeException if <code>throwable</code> is not
* an instance of java.lang.Throwable in the target VM
- * @throws IllegalThreadStateException if the thread has terminated
- * @throws UnsupportedOperationException if the thread is a virtual
- * thread and the target VM does not support this operation on
- * virtual threads
+ * @throws IllegalThreadStateException if the thread has terminated,
+ * or if the thread is a virtual thread and was not suspended
+ * @throws OpaqueFrameException if the thread is a suspended
+ * virtual thread and the implementation was unable to throw an
+ * asynchronous exception from the thread's current frame
* @throws VMCannotBeModifiedException if the VirtualMachine is read-only
* @see VirtualMachine#canBeModified()
*/