@@ -254,12 +254,36 @@ findThread(ThreadList *list, jthread thread)
254254 node = nonTlsSearch (getEnv (), & otherThreads , thread );
255255 }
256256 /*
257- * Search runningThreads list. The TLS lookup may have failed because the
258- * thread has terminated, but the ThreadNode may still be present.
257+ * Normally we can assume that a thread with no TLS will never be in the runningThreads
258+ * list. This is because we always set the TLS when adding to runningThreads.
259+ * However, when a thread exits, its TLS is automatically cleared. Normally this
260+ * is not a problem because the debug agent will first get a THREAD_END event,
261+ * and that will cause the thread to be removed from runningThreads, thus we
262+ * avoid this situation of having a thread in runningThreads, but with no TLS.
263+ *
264+ * However... there is one exception to this. While handling VM_DEATH, the first thing
265+ * the debug agent does is clear all the callbacks. This means we will no longer
266+ * get THREAD_END events as threads exit. This means we might find threads on
267+ * runningThreads with no TLS during VM_DEATH. Essentially the THREAD_END that
268+ * would normally have resulted in removing the thread from runningThreads is
269+ * missed, so the thread remains on runningThreads.
270+ *
271+ * The end result of all this is that if the TLS lookup failed, we still need to check
272+ * if the thread is on runningThreads, but only if JVMTI callbacks have been cleared.
273+ * Otherwise the thread should not be on the runningThreads.
259274 */
260- if ( node == NULL ) {
261- if ( list == NULL || list == & runningThreads ) {
262- node = nonTlsSearch (getEnv (), & runningThreads , thread );
275+ if ( !gdata -> jvmtiCallBacksCleared ) {
276+ /* The thread better not be on runningThreads if the TLS lookup failed. */
277+ JDI_ASSERT (!nonTlsSearch (getEnv (), & runningThreads , thread ));
278+ } else {
279+ /*
280+ * Search the runningThreads list. The TLS lookup may have failed because the
281+ * thread has terminated, but we never got the THREAD_END event.
282+ */
283+ if ( node == NULL ) {
284+ if ( list == NULL || list == & runningThreads ) {
285+ node = nonTlsSearch (getEnv (), & runningThreads , thread );
286+ }
263287 }
264288 }
265289 }
0 commit comments