RFR: JDK-8210252: com/sun/jdi/DebuggerThreadTest.java fails with NPE
Gary Adams
gary.adams at oracle.com
Wed Sep 5 18:26:11 UTC 2018
If we go ahead with this proposed fix, the next time it fails
we will have more information about the other threads
captured in the log.
One last observation, the test that failed was running with UseZGC.
Not sure how that might impact this particular test.
On 9/5/18, 2:07 PM, Chris Plummer wrote:
>
> Hi Gary,
>
>> If the DebugThreadTarg is resumed prematurely,
>
> The failure explanation seems to hinge on this, but I don't see how
> this can happen. What is resuming DebugThreadTarg? Only the call to
> listenUntilVMDisconnect() should be doing this, and we aren't even
> getting that far. The only thing I can think of is due to some other
> issue (maybe host out of memory so process was killed off), the
> DebugThreadTarg process has exited unexpectedly. In this case I guess
> the fix you have is appropriate defensive programming, causing the
> test to fail when this happens, but still won't explain why it happens
> and also won't prevent future failures of this test. Also, this type
> of Debuggee early exit problem could happen with other tests too. I'm
> leaning towards just closing this bug as CNR. I don't think we want to
> be writing our tests to defend against random system related failures,
> especially when the end result is still going to be a test failure
> that we don't fully understand.
>
> thanks,
>
> Chris
>
> On 9/5/18 7:33 AM, Gary Adams wrote:
>> The DebuggerThreadTest ensures it is in sync
>> at the beginning of RunTests with a breakpoint event
>> in DebuggerThreadTarg ready() method.
>>
>> The DebuggerThreadTest then continues with
>> dumpThreads() and listenUntilVMDisconnect()
>> completes.
>>
>> If the DebugThreadTarg is resumed prematurely,
>> the main thread in the debuggee could complete
>> before the dumpThreads enumeration is complete.
>>
>> DebuggerThreadTest
>> main()
>> startTests()
>> runTests()
>> startTo( "DebuggerThreadTarg.ready()")
>> dumpThreads()
>> listenUntilVMDisconnect()
>>
>> DebuggerThreadTarg
>> main()
>> ready()
>>
>> Revised fix:
>> - Prevents the NPE from a finished thread group
>> - Fails the test with a message indicating
>> number of premature completed threads.
>>
>> diff --git a/test/jdk/com/sun/jdi/DebuggerThreadTest.java
>> b/test/jdk/com/sun/jdi/DebuggerThreadTest.java
>> --- a/test/jdk/com/sun/jdi/DebuggerThreadTest.java
>> +++ b/test/jdk/com/sun/jdi/DebuggerThreadTest.java
>> @@ -1,5 +1,5 @@
>> /*
>> - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All
>> rights reserved.
>> + * Copyright (c) 2001, 2018, 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
>> @@ -76,8 +76,16 @@
>> Thread list[] = new Thread[listThreads * 2];
>> int gotThreads = tg.enumerate(list, true);
>> for (int i = 0; i < Math.min(gotThreads, list.length); i++){
>> + int finishedThreads = 0;
>> Thread t = list[i];
>> - String groupName = t.getThreadGroup().getName();
>> + ThreadGroup tga = t.getThreadGroup();
>> + String groupName;
>> + if (tga == null) {
>> + groupName = "<completed>";
>> + finishedThreads++ ;
>> + } else {
>> + groupName =tga.getName();
>> + }
>>
>> System.out.println("Thread [" + i + "] group = '" +
>> groupName +
>> @@ -89,7 +97,10 @@
>> failure("FAIL: non-daemon thread '" + t.getName() +
>> "' found in ThreadGroup '" + groupName + "'");
>> }
>> -
>> + if (finishedThreads > 0 ) {
>> + failure("FAIL: " + finishedThreads +
>> + " threads completed while VM suspended.");
>> + }
>> }
>> }
>>
>>
>> On 9/4/18, 3:15 PM, Chris Plummer wrote:
>>> Hi Gary,
>>>
>>> The failed case only had:
>>>
>>> Thread [0] group = 'system' name = 'Reference Handler' daemon = true
>>> Thread [1] group = 'system' name = 'Finalizer' daemon = true
>>> Thread [2] group = 'system' name = 'Signal Dispatcher' daemon = true
>>> Thread [3] group = 'system' name = 'process reaper' daemon = true
>>>
>>> That would indicate that 'main' is likely the thread that exited.
>>> Seems odd. Isn't that the thread that the test is executing in?
>>>
>>> If you can't reproduce it, maybe it would be better to commit a
>>> diagnostic fix like the one I suggested and keep an eye on it.
>>> However, it only seems to have failed once due to this reason, so
>>> unless it is a new problem we may never see it again.
>>>
>>> Chris
>>>
>>> On 9/4/18 11:28 AM, Gary Adams wrote:
>>>> I haven't been able to reproduce the problem locally.
>>>> Trying larger test runs on mach5 now.
>>>>
>>>> Here's the output from a successful test run.
>>>> If any of the threads exited, they would have a null group name.
>>>>
>>>> Howdy!
>>>> Thread [0] group = 'system' name = 'Reference Handler' daemon = true
>>>> Thread [1] group = 'system' name = 'Finalizer' daemon = true
>>>> Thread [2] group = 'system' name = 'Signal Dispatcher' daemon = true
>>>> Thread [3] group = 'system' name = 'process reaper' daemon = true
>>>> Thread [4] group = 'main' name = 'main' daemon = false
>>>> Thread [5] group = 'main' name = 'pool-1-thread-1' daemon = true
>>>> Thread [6] group = 'AgentVMThreadGroup' name = 'AgentVMThread'
>>>> daemon = false
>>>> Thread [7] group = 'AgentVMThreadGroup' name = 'output reader'
>>>> daemon = false
>>>> Thread [8] group = 'AgentVMThreadGroup' name = 'output reader'
>>>> daemon = false
>>>> Thread [9] group = 'AgentVMThreadGroup' name = 'Thread-5' daemon =
>>>> true
>>>> Thread [10] group = 'InnocuousThreadGroup' name = 'Common-Cleaner'
>>>> daemon = true
>>>> Thread [11] group = 'JDI [1485331767]' name = 'JDI Internal Event
>>>> Handler' daemon = true
>>>> Thread [12] group = 'JDI [1485331767]' name = 'JDI Target VM
>>>> Interface' daemon = true
>>>> Goodbye from DebuggerThreadTarg!
>>>>
>>>>
>>>> On 9/4/18, 2:16 PM, Chris Plummer wrote:
>>>>> Can you reproduce the problem? If so, maybe to find out which
>>>>> thread is a problem you could check for null, print the thread
>>>>> info, and then fail the test.
>>>>>
>>>>> Chris
>>>>>
>>>>> On 9/4/18 11:14 AM, Gary Adams wrote:
>>>>>> I'm not sure which thread exited causes the NPE.
>>>>>> This patch will let the test continue and at least
>>>>>> let the list of threads be processed.
>>>>>>
>>>>>> The test walks up the parents to the initial thread
>>>>>> and then "enumerates()" the set of the threads to check.
>>>>>> There is an inherent race condition in enumerate()
>>>>>> that recognizes it is a snapshot of a moving target.
>>>>>>
>>>>>> On 9/4/18, 1:51 PM, Chris Plummer wrote:
>>>>>>> Hi Gary,
>>>>>>>
>>>>>>> Why has the thread exited if the debuggee is still running?
>>>>>>>
>>>>>>> Chris
>>>>>>>
>>>>>>> On 9/4/18 5:22 AM, Gary Adams wrote:
>>>>>>>> Here's a quick fix to avoid the NPE using a getThreadGroup()
>>>>>>>> which could be null
>>>>>>>> if the thread has terminated.
>>>>>>>>
>>>>>>>> Issue: https://bugs.openjdk.java.net/browse/JDK-8210252
>>>>>>>>
>>>>>>>> diff --git a/test/jdk/com/sun/jdi/DebuggerThreadTest.java
>>>>>>>> b/test/jdk/com/sun/jdi/DebuggerThreadTest.java
>>>>>>>> --- a/test/jdk/com/sun/jdi/DebuggerThreadTest.java
>>>>>>>> +++ b/test/jdk/com/sun/jdi/DebuggerThreadTest.java
>>>>>>>> @@ -77,7 +77,8 @@
>>>>>>>> int gotThreads = tg.enumerate(list, true);
>>>>>>>> for (int i = 0; i < Math.min(gotThreads, list.length);
>>>>>>>> i++){
>>>>>>>> Thread t = list[i];
>>>>>>>> - String groupName = t.getThreadGroup().getName();
>>>>>>>> + ThreadGroup tga = t.getThreadGroup();
>>>>>>>> + String groupName = (tga == null ? "<completed>": tga.getName());
>>>>>>>>
>>>>>>>> System.out.println("Thread [" + i + "] group = '" +
>>>>>>>> groupName +
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>
>>>
>>
>
More information about the serviceability-dev
mailing list