8289765: JDI EventSet/resume/resume008 failed with "ERROR: suspendCounts don't match for : VirtualThread-unparker"

Reviewed-by: sspitsyn, kevinw
(cherry picked from commit 8b0eb7299a)
This commit is contained in:
Chris Plummer
2023-03-09 21:55:15 +00:00
committed by Vitaly Provodin
parent 705f5d6922
commit 3c2e9b99a5
4 changed files with 96 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -112,17 +112,17 @@ public class resume008 extends TestDebuggerType1 {
case 0:
eventRequest = settingThreadStartRequest (
SUSPEND_NONE, "ThreadStartRequest1");
SUSPEND_NONE, "ThreadStartRequest0");
break;
case 1:
eventRequest = settingThreadStartRequest (
SUSPEND_THREAD, "ThreadStartRequest2");
SUSPEND_THREAD, "ThreadStartRequest1");
break;
case 2:
eventRequest = settingThreadStartRequest (
SUSPEND_ALL, "ThreadStartRequest3");
SUSPEND_ALL, "ThreadStartRequest2");
break;
@@ -137,13 +137,24 @@ public class resume008 extends TestDebuggerType1 {
EventIterator eventIterator = eventSet.eventIterator();
Event newEvent = eventIterator.nextEvent();
display(" got new event: " + newEvent);
// Make sure any spurious ThreadStartEvent got filtered out.
if (newEvent instanceof ThreadStartEvent) {
ThreadStartEvent t = (ThreadStartEvent)newEvent;
if (!t.thread().name().equals(resume008a.THREAD_NAME_PREFIX + i)) {
setFailedStatus("ERROR: ThreadStartEvent is not for expected thread: " +
t.thread().name());
return;
}
}
if ( !(newEvent instanceof ThreadStartEvent)) {
setFailedStatus("ERROR: new event is not ThreadStartEvent");
} else {
String property = (String) newEvent.request().getProperty("number");
display(" got new ThreadStartEvent with propety 'number' == "
display(" got new ThreadStartEvent with property 'number' == "
+ property);
display("......checking up on EventSet.resume()");
@@ -263,7 +274,6 @@ public class resume008 extends TestDebuggerType1 {
String property) {
try {
ThreadStartRequest tsr = eventRManager.createThreadStartRequest();
tsr.addCountFilter(1);
tsr.setSuspendPolicy(suspendPolicy);
tsr.putProperty("number", property);
return tsr;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,8 @@ public class resume008a {
static final int FAILED = 2;
static final int PASS_BASE = 95;
static final String THREAD_NAME_PREFIX = "resume008-thread";
static ArgumentHandler argHandler;
static Log log;
@@ -95,18 +97,18 @@ public class resume008a {
switch (i) {
//------------------------------------------------------ section tested
case 0:
thread0 = JDIThreadFactory.newThread(new Threadresume008a("thread0"));
thread0 = JDIThreadFactory.newThread(new Threadresume008a(THREAD_NAME_PREFIX + 0));
methodForCommunication();
threadStart(thread0);
thread1 = JDIThreadFactory.newThread(new Threadresume008a("thread1"));
thread1 = JDIThreadFactory.newThread(new Threadresume008a(THREAD_NAME_PREFIX + 1));
// Wait for debugger to complete the first test case
// before advancing to the first breakpoint
// before advancing to the 2nd breakpoint
waitForTestCase(0);
methodForCommunication();
break;
case 1:
threadStart(thread1);
thread2 = JDIThreadFactory.newThread(new Threadresume008a("thread2"));
thread2 = JDIThreadFactory.newThread(new Threadresume008a(THREAD_NAME_PREFIX + 2));
methodForCommunication();
break;
case 2:
@@ -139,6 +141,7 @@ public class resume008a {
}
// Synchronize with debugger progression.
static void waitForTestCase(int t) {
log1("waitForTestCase: " + t);
while (testCase < t) {
try {
Thread.sleep(100);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -331,16 +331,24 @@ public class EventFilters
}
public static boolean filtered(Event event) {
if (event.toString().contains("VM JFR Buffer Thread"))
return true;
if (event.toString().contains("JFR request timer"))
return true;
// Filter out any carrier thread that starts while running the test.
if (event.toString().contains("ForkJoinPool"))
return true;
if (event instanceof ThreadStartEvent) {
ThreadStartEvent tse = (ThreadStartEvent)event;
String tname = tse.thread().name();
String knownThreads[] = {
"VM JFR Buffer Thread",
"JFR request timer",
"Reference Handler",
"VirtualThread-unparker",
"Common-Cleaner",
"FinalizerThread",
"ForkJoinPool"
};
for (String s : knownThreads) {
if (tname.startsWith(s)) {
return true;
}
}
}
return false;
}

View File

@@ -251,6 +251,41 @@ public class EventHandler implements Runnable {
defaultExceptionRequest.enable();
}
/**
* Creates an EventListener for unexpected ThreadStartEvents. The
* events are ignored.
*/
public EventListener createSpuriousThreadStartEventListener(String owner) {
/*
* This listener catches spurious thread creations that we want to ignore.
*/
return (new EventListener() {
boolean handled = false;
public boolean eventReceived(Event event) {
handled = false;
if (event instanceof ThreadStartEvent) {
if (EventFilters.filtered(event)) {
display(owner + ": Ignoring spurious thread creation: " + event);
handled = true;
}
}
return handled;
}
public void eventSetComplete(EventSet set) {
// If we ignored this event, then we need to resume.
if (handled) {
handled = false; // reset for next EventSet that comes in.
display(owner + ": set.resume() after spurious thread creation: " + set);
set.resume();
}
}
}
);
}
/**
* This method sets up default listeners.
*/
@@ -343,6 +378,13 @@ public class EventHandler implements Runnable {
}
}
);
/**
* This listener attempt to catch any ThreadStartEvent for a thread not
* created by the test. It prevents the "Unexpected event" listener
* above from complaining about these events.
*/
addListener(createSpuriousThreadStartEventListener("Default Listener"));
}
/**
@@ -404,12 +446,13 @@ public class EventHandler implements Runnable {
en.set = set;
EventHandler.this.notifyAll();
}
return true;
return true; // event was handled
}
}
return false;
return false; // event was not handled
}
};
if (shouldRemoveListeners) {
display("waitForRequestedEventCommon: enabling remove of listener " + listener);
listener.enableRemovingThisListener();
@@ -419,6 +462,13 @@ public class EventHandler implements Runnable {
}
addListener(listener);
/*
* This listener skips spurious thread creations that we want to ignore.
*/
EventListener spuriousThreadStartEventListener =
createSpuriousThreadStartEventListener("waitForRequestedEventCommon");
addListener(spuriousThreadStartEventListener);
/*
* This listener logs each EventSet received.
*/
@@ -452,6 +502,7 @@ public class EventHandler implements Runnable {
requests[i].disable();
}
}
removeListener(spuriousThreadStartEventListener);
removeListener(eventLogListener);
return en;
}