sped up threadNode lookups in the debug agent. It also added an assert that ended up getting triggered. The assert was in findThread(), where it was making sure that if a thread did not have a TLS, it would not be found in the runningThreads list.
was filed for this assert issue, and a quick fix was done that disabled the assert, but also required some extra thread lookup logic for correctness, which partly undid some of the speed ups introduced by
. The CR is for properly fixing
without undoing any of the speedup introduced by
The root cause of
is that during VM shutdown a VM_DEATH event is sent, and this causes the debug agent to disable all JVMTI callbacks, which means the agent no longer receives THREAD_END events. The THREAD_END event is important for triggering the removal of the thread from runningThreads. When the thread is in the process of exiting, JVMTI strips it of its TLS, and it's important that the debug agent gets the THREAD_END event before this happens, but since callbacks are disabled, the THREAD_END event is not received.
During VM_DEATH handling, the debugger was also doing a VM.resume(), which calls commonResumeList(), which first walks runningThreads to build a list of threads that need to be resumed. After resuming these threads, it then walks this list of resumed threads, calling findThread() on each so it can do some bookkeeping on the ThreadNode. This is when sometimes we run into a thread that is on the list but no longer has a TLS. It basically has exited without the debug agent seeing a THREAD_END.
The fix is when handling VM_DEATH, don't have findThread() do the assert that checks if a thread has no TLS but is on runningThreads. Instead, if the thread has no TLS, then also look it up on runningThreads. Note normally we want to avoid this lookup (this is part of what
optimized), but in this rare case of dealing with VM_DEATH, it is ok to do without impacting performance.