RFR JDK-8170089: nsk/jdi/EventSet/resume/resume008: ERROR: suspendCounts don't match for : Common-Cleaner
serguei.spitsyn at oracle.com
serguei.spitsyn at oracle.com
Wed Jul 25 01:01:44 UTC 2018
Hi Gary,
+1
Thanks,
Serguei
On 7/24/18 16:46, Chris Plummer wrote:
> Hi Gary,
>
> It looks like that should work fine.
>
> thanks,
>
> Chris
>
> On 7/24/18 12:28 PM, Gary Adams wrote:
>> Here's a quick prototype to add a variable to the debuggee.
>> The debugger sets it at the end of each completed test case.
>>
>> The debuggee can then check for the value change to delay
>> hitting the breakpoint which interfered with suspend count checks.
>>
>> Would need to add a bit more error and timeout checking to
>> complete the fix. Should also check if the other resume008 test cases
>> need similar synchronization. Could possibly migrate the code up to
>> TestDebuggerType1 if other tests also needed this generic capability.
>>
>>
>> diff --git
>> a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008.java
>> b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008.java
>> ---
>> a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008.java
>> +++
>> b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008.java
>> @@ -63,6 +63,9 @@
>> * to be resulting in the event.
>> * - Upon getting new event, the debugger
>> * performs the check corresponding to the event.
>> + * - The debugger informs the debuggee when it completes
>> + * each test case, so it will wait before hitting
>> + * communication breakpoints.
>> */
>>
>> public class resume008 extends TestDebuggerType1 {
>> @@ -234,6 +237,7 @@
>>
>> default: throw new Failure("** default case 1
>> **");
>> }
>> + informDebuggeeTestCase(i);
>> }
>>
>> display("......--> vm.resume()");
>> @@ -255,4 +259,25 @@
>> }
>> }
>>
>> + /**
>> + * Inform debuggee which thread test the debugger has completed.
>> + * Used for synchronization, so the debuggee does not move too
>> quickly.
>> + * @param testCase index of just completed test
>> + */
>> + void informDebuggeeTestCase(int testCase) {
>> + if (!EventHandler.isDisconnected() && debuggeeClass != null) {
>> + try {
>> + ((ClassType)debuggeeClass)
>> + .setValue(debuggeeClass.fieldByName("testCase"),
>> + vm.mirrorOf(testCase));
>> + } catch (InvalidTypeException ite) {
>> + // ignored
>> + } catch (ClassNotLoadedException cnle) {
>> + // ignored
>> + } catch (VMDisconnectedException e) {
>> + // ignored
>> }
>> + }
>> + }
>> +
>> +}
>>
>>
>> diff --git
>> a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008a.java
>> b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008a.java
>> ---
>> a/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008a.java
>> +++
>> b/test/hotspot/jtreg/vmTestbase/nsk/jdi/EventSet/resume/resume008a.java
>> @@ -62,6 +62,7 @@
>>
>> static int exitCode = PASSED;
>>
>> + static int testCase = -1;
>> static int instruction = 1;
>> static int end = 0;
>> // static int quit = 0;
>> @@ -104,6 +105,15 @@
>> threadStart(thread0);
>>
>> thread1 = new Threadresume008a("thread1");
>> + // Wait for debugger to complete the
>> first test case
>> + // before advancing to the next breakpoint
>> + while (testCase < 0) {
>> + try {
>> + Thread.sleep(100);
>> + } catch (InterruptedException e) {
>> + // ignored
>> + }
>> + }
>> methodForCommunication();
>> break;
>>
>>
>> On 7/20/18, 2:37 PM, Chris Plummer wrote:
>>> Hi Gary,
>>>
>>> The test fails if the breakpoint event comes in after the test
>>> captures the initial thread suspend counts and before the test
>>> captures the 2nd suspend counts.
>>>
>>> debugger> getting : Map<String, Integer> suspendsCounts1
>>> debugger> {Reference Handler=1, Common-Cleaner=1, main=1, Signal
>>> Dispatcher=1, Finalizer=1}
>>> debugger> eventSet.resume;
>>> debugger> getting : Map<String, Integer> suspendsCounts2
>>> EventHandler> Received event set with policy = SUSPEND_ALL
>>> EventHandler> Event: BreakpointEventImpl req breakpoint request
>>> nsk.jdi.EventSet.resume.resume008a:60 (enabled)
>>> debugger> Received communication breakpoint event.
>>> debugger> {Reference Handler=2, Common-Cleaner=2, main=1, Signal
>>> Dispatcher=2, Finalizer=2}
>>>
>>> So we end up with some threads starting with 1 suspend and ending
>>> with 2 (not clear to me why main is still at 1).
>>>
>>> It will pass if the breakpoint comes in after it does both of
>>> suspend count checks, as you have shown with the sleep(100)
>>> solution. Output looks like this:
>>>
>>> debugger> got new ThreadStartEvent with propety 'number' ==
>>> ThreadStartRequest1
>>> ...
>>> debugger> ......--> vm.suspend();
>>> debugger> getting : Map<String, Integer> suspendsCounts1
>>> debugger> {Reference Handler=1, thread0=1, Common-Cleaner=1, main=1,
>>> Signal Dispatcher=1, Finalizer=1}
>>> debugger> eventSet.resume;
>>> debugger> getting : Map<String, Integer> suspendsCounts2
>>> debugger> {Reference Handler=1, thread0=1, Common-Cleaner=1, main=1,
>>> Signal Dispatcher=1, Finalizer=1}
>>> ...
>>> debugger> Received communication breakpoint event.
>>>
>>> I've also shown that it passes if the breakpoint always comes in
>>> before capturing the initial suspend counts. I added a sleep on the
>>> debugger side right after eventHandler.waitForRequestedEventSet()
>>> returns. Output looks like:
>>>
>>> debugger> Received communication breakpoint event.
>>> debugger> got new ThreadStartEvent with propety 'number' ==
>>> ThreadStartRequest1
>>> ...
>>> debugger> ......--> vm.suspend();
>>> debugger> getting : Map<String, Integer> suspendsCounts1
>>> debugger> {Reference Handler=2, thread0=2, Common-Cleaner=2, main=2,
>>> Signal Dispatcher=2, Finalizer=2}
>>> debugger> eventSet.resume;
>>> debugger> getting : Map<String, Integer> suspendsCounts2
>>> debugger> {Reference Handler=2, thread0=2, Common-Cleaner=2, main=2,
>>> Signal Dispatcher=2, Finalizer=2}
>>>
>>> I think we should add synchronization to force one of these two
>>> outcomes. For the first, you would need to make the debugger modify
>>> some variable that the debuggee is watching (sitting in a loop
>>> waiting for it to change). For the second, you can rely on the
>>> existing methodForCommunication() approach. You just need to
>>> restructure the debugger a bit. I had started down this path late
>>> Wednesday, but got sidetracked by a few other things. I can look
>>> into it some more if you'd like.
>>>
>>> thanks,
>>>
>>> Chris
>
More information about the serviceability-dev
mailing list