Skip to content

Commit 1d517af

Browse files
committed
8305209: JDWP exit error AGENT_ERROR_INVALID_THREAD(203): missing entry in running thread table
Reviewed-by: sspitsyn, lmesnik
1 parent 08fbb7b commit 1d517af

File tree

3 files changed

+33
-5
lines changed

3 files changed

+33
-5
lines changed

src/jdk.jdwp.agent/share/native/libjdwp/threadControl.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,17 +253,24 @@ findThread(ThreadList *list, jthread thread)
253253
* Otherwise the thread should not be on the runningThreads.
254254
*/
255255
if ( !gdata->jvmtiCallBacksCleared ) {
256-
/* The thread better not be on runningThreads if the TLS lookup failed. */
256+
/* The thread better not be on either list if the TLS lookup failed. */
257257
JDI_ASSERT(!nonTlsSearch(getEnv(), &runningThreads, thread));
258+
JDI_ASSERT(!nonTlsSearch(getEnv(), &runningVThreads, thread));
258259
} else {
259260
/*
260-
* Search the runningThreads list. The TLS lookup may have failed because the
261-
* thread has terminated, but we never got the THREAD_END event.
261+
* Search the runningThreads and runningVThreads lists. The TLS lookup may have
262+
* failed because the thread has terminated, but we never got the THREAD_END event.
263+
* The big comment above explains why this can happen.
262264
*/
263265
if ( node == NULL ) {
264266
if ( list == NULL || list == &runningThreads ) {
265267
node = nonTlsSearch(getEnv(), &runningThreads, thread);
266268
}
269+
if ( node == NULL ) {
270+
if ( list == NULL || list == &runningVThreads ) {
271+
node = nonTlsSearch(getEnv(), &runningVThreads, thread);
272+
}
273+
}
267274
}
268275
}
269276
}

test/jdk/com/sun/jdi/TestScaffold.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,21 @@ public synchronized void waitForVMDisconnect() {
710710
} catch (InterruptedException e) {
711711
}
712712
}
713+
714+
// Make sure debuggee exits with no errors. Otherwise failures might go unnoticed.
715+
Process p = vm.process();
716+
try {
717+
p.waitFor();
718+
} catch (InterruptedException e) {
719+
throw new RuntimeException(e);
720+
}
721+
int res = p.exitValue();
722+
// Some tests purposefully exit with an exception, which produces exitValue
723+
// 1, so we have to allow it also.
724+
if (res != 0 && res != 1) {
725+
throw new RuntimeException("Non-zero debuggee exitValue: " + res);
726+
}
727+
713728
traceln("TS: waitForVMDisconnect: done");
714729
}
715730

test/jdk/com/sun/jdi/ThreadMemoryLeakTest.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,20 @@ public static void main(String[] args) throws InterruptedException {
5858
while (System.currentTimeMillis() - startTime < 100 * 1000) {
5959
iterations++;
6060
semaphore.acquire();
61-
Executors.defaultThreadFactory().newThread(() -> {
61+
TestScaffold.newThread(() -> {
6262
adder.increment();
6363
long sum = adder.sum();
6464
if ((sum % 1000) == 0) {
6565
System.out.println("Progress: " + sum);
6666
}
6767
try {
68-
Thread.sleep(50);
68+
String mainWrapper = System.getProperty("main.wrapper");
69+
// Virtual thread creation tends to overwhelm the debugger,
70+
// leading to high memory use for all the unprocessed events
71+
// that get queued up, so we need to slow it down a bit more
72+
// than we do for platform threads to avoid getting OOME.
73+
long timeToSleep = "Virtual".equals(mainWrapper) ? 100 : 50;
74+
Thread.sleep(timeToSleep);
6975
}
7076
catch (InterruptedException e) {
7177
throw new RuntimeException(e);

0 commit comments

Comments
 (0)