Skip to content

Commit

Permalink
8289765: JDI EventSet/resume/resume008 failed with "ERROR: suspendCou…
Browse files Browse the repository at this point in the history
…nts don't match for : VirtualThread-unparker"

Reviewed-by: sspitsyn, kevinw
  • Loading branch information
plummercj committed Mar 9, 2023
1 parent 5726d31 commit 8b0eb72
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 24 deletions.
@@ -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
Expand Down Expand Up @@ -112,17 +112,17 @@ protected void testRun() {

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;


Expand All @@ -137,13 +137,24 @@ protected void testRun() {

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()");
Expand Down Expand Up @@ -263,7 +274,6 @@ private ThreadStartRequest settingThreadStartRequest(int suspendPolicy,
String property) {
try {
ThreadStartRequest tsr = eventRManager.createThreadStartRequest();
tsr.addCountFilter(1);
tsr.setSuspendPolicy(suspendPolicy);
tsr.putProperty("number", property);
return tsr;
Expand Down
@@ -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
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -95,18 +97,18 @@ public static void main (String argv[]) {
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:
Expand Down Expand Up @@ -139,6 +141,7 @@ static int threadStart(Thread t) {
}
// Synchronize with debugger progression.
static void waitForTestCase(int t) {
log1("waitForTestCase: " + t);
while (testCase < t) {
try {
Thread.sleep(100);
Expand Down
30 changes: 19 additions & 11 deletions test/hotspot/jtreg/vmTestbase/nsk/share/jdi/EventFilters.java
@@ -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
Expand Down Expand Up @@ -331,16 +331,24 @@ public boolean isObjectMatch(ObjectReference eventObject, ThreadReference eventT
}

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;
}

Expand Down
55 changes: 53 additions & 2 deletions test/hotspot/jtreg/vmTestbase/nsk/share/jdi/EventHandler.java
Expand Up @@ -251,6 +251,41 @@ private void createDefaultEventRequests() {
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.
*/
Expand Down Expand Up @@ -343,6 +378,13 @@ public boolean eventReceived(Event event) {
}
}
);

/**
* 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"));
}

/**
Expand Down Expand Up @@ -404,12 +446,13 @@ public boolean eventReceived(Event event) {
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();
Expand All @@ -419,6 +462,13 @@ public boolean eventReceived(Event event) {
}
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.
*/
Expand Down Expand Up @@ -452,6 +502,7 @@ public void eventSetReceived(EventSet set) {
requests[i].disable();
}
}
removeListener(spuriousThreadStartEventListener);
removeListener(eventLogListener);
return en;
}
Expand Down

1 comment on commit 8b0eb72

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.