If StopThread is done when the thread is in certain various states (but not all states), after the async exception is delivered and handled, hotspot leaves the thread's "interrupted" flag set. The end result is the next time the thread does something like Thread.sleep(), it will immediately get an InterruptedException.
I've only been observing this with platform threads, not virtual threads, but that might be because the carrier thread is getting the flag set, and it is not seen from the virtual thread.
I'm seeing the "interrupted" flag being left set after StopThread (and the thread resumed if it was previously suspended) in each of the following situations:
- thread suspended at a breakpoint
- thread in a loop and suspended
- thread in a loop and not suspended
I do not see the "interrupted" flag being left set after:
- thread suspended in Thread.sleep()
The workaround for this is to call Thread.interrupted() to clear the pending interrupt, but of course this is only possible if the code knows when/where to expect an async exception.
The "interrupted" flag seems to be getting set here:
void JavaThread::install_async_exception(AsyncExceptionHandshake* aeh) {
// Do not throw asynchronous exceptions against the compiler thread
// or if the thread is already exiting.
if (!can_call_java() || is_exiting()) {
delete aeh;
return;
}
. . .
// Interrupt thread so it will wake up from a potential wait()/sleep()/park()
java_lang_Thread::set_interrupted(threadObj(), true);
this->interrupt();
}
The following seems to fix the issue, but it is not known if this is the correct fix, or if it may cause other problems:
diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp
index 473ce59c751..16e794d3474 100644
--- a/src/hotspot/share/runtime/javaThread.cpp
+++ b/src/hotspot/share/runtime/javaThread.cpp
@@ -1062,6 +1062,7 @@ void JavaThread::handle_async_exception(oop java_throwable) {
// We cannot call Exceptions::_throw(...) here because we cannot block
set_pending_exception(java_throwable, __FILE__, __LINE__);
+ java_lang_Thread::set_interrupted(threadObj(), false);
clear_scopedValueBindings();
I've only been observing this with platform threads, not virtual threads, but that might be because the carrier thread is getting the flag set, and it is not seen from the virtual thread.
I'm seeing the "interrupted" flag being left set after StopThread (and the thread resumed if it was previously suspended) in each of the following situations:
- thread suspended at a breakpoint
- thread in a loop and suspended
- thread in a loop and not suspended
I do not see the "interrupted" flag being left set after:
- thread suspended in Thread.sleep()
The workaround for this is to call Thread.interrupted() to clear the pending interrupt, but of course this is only possible if the code knows when/where to expect an async exception.
The "interrupted" flag seems to be getting set here:
void JavaThread::install_async_exception(AsyncExceptionHandshake* aeh) {
// Do not throw asynchronous exceptions against the compiler thread
// or if the thread is already exiting.
if (!can_call_java() || is_exiting()) {
delete aeh;
return;
}
. . .
// Interrupt thread so it will wake up from a potential wait()/sleep()/park()
java_lang_Thread::set_interrupted(threadObj(), true);
this->interrupt();
}
The following seems to fix the issue, but it is not known if this is the correct fix, or if it may cause other problems:
diff --git a/src/hotspot/share/runtime/javaThread.cpp b/src/hotspot/share/runtime/javaThread.cpp
index 473ce59c751..16e794d3474 100644
--- a/src/hotspot/share/runtime/javaThread.cpp
+++ b/src/hotspot/share/runtime/javaThread.cpp
@@ -1062,6 +1062,7 @@ void JavaThread::handle_async_exception(oop java_throwable) {
// We cannot call Exceptions::_throw(...) here because we cannot block
set_pending_exception(java_throwable, __FILE__, __LINE__);
+ java_lang_Thread::set_interrupted(threadObj(), false);
clear_scopedValueBindings();
- relates to
-
JDK-8306034 add support of virtual threads to JVMTI StopThread
-
- Resolved
-