RFR 8193879: Java debugger hangs on method invocation
Alex Menkov
alexey.menkov at oracle.com
Thu Oct 4 21:53:07 UTC 2018
On 10/04/2018 10:28, Chris Plummer wrote:
> On 10/4/18 5:12 AM, Gary Adams wrote:
>> In TTY.java do you need to force a simple prompt for the
>> breakpoint event output? What prevents currentThread from
>> being set at the time you are printing the prompt?
>>
>>
>> 103 // Print the prompt if suspend policy is
>> SUSPEND_EVENT_THREAD. In case of
>> 104 // SUSPEND_ALL policy this is handled by vmInterrupted()
>> method.
>> 105 if (be.request().suspendPolicy() ==
>> EventRequest.SUSPEND_EVENT_THREAD) {
>> 106 MessageOutput.println();
>> 107 MessageOutput.printPrompt();
> Normally the thread is suspended after the above code is executed:
>
> public void run() {
> EventQueue queue = Env.vm().eventQueue();
> while (connected) {
> try {
> EventSet eventSet = queue.remove();
> boolean resumeStoppedApp = false;
> EventIterator it = eventSet.eventIterator();
> while (it.hasNext()) {
> resumeStoppedApp |= !handleEvent(it.nextEvent());
> <--- calls the modified code above
> }
>
> if (resumeStoppedApp) {
> eventSet.resume();
> } else if (eventSet.suspendPolicy() ==
> EventRequest.SUSPEND_ALL) {
> setCurrentThread(eventSet); <------
> notifier.vmInterrupted();
> }
>
> However, it only calls setCurrentThread() for SUSPEND_ALL policies. So
> what Daniil has done here is make it print a simple prompt if the policy
> is SUSPEND_EVENT_THREAD. It's unclear to me what the actual debugger
> behavior is in this case. Don't we still suspend and get a prompt from
> which we can type in the next command? In this case, wouldn't you want a
> full prompt? Related to that question, why is vmInterrupted() only
> called if we suspend all threads, and not when we just suspend the
> thread that the breakpoint came in on?
Did a quick test
- run debuggee (suspended), connect jdb:
===========
VM Started: No frames on the current call stack
main[1] stop thread at myclass:71
Deferring breakpoint myclass:71.
It will be set after the class is loaded.
main[1] run
> Set deferred breakpoint myclass:71
Breakpoint hit:
=====
I.e. we get only "Breakpoint hit: " without any info about the thread
(and this doesn't look good), current thread is not set ("next" reports
"Nothing suspended.")
But if we handle SUSPEND_EVENT_THREAD like SUSPEND_ALL, we need to think
how to handle possible race conditions when there are 2 threads, each of
them is stopped by "stop thread at/in".
Some notes about the fix (actually about the tests as the fix itself
should be implemented):
JdbStopThreadWithTraceOnTest.java
70 jdb.command("stop thread at " + DEBUGGEE_CLASS + ":" + bpLine);
It would be better to introduce
public static JdbCommand JdbCommand.stopThreadAt(String targetClass, int
lineNum)
Actually may be it would be better to drop Jdb.command(String) - it's
required only by CommandCommentDelimiter (need to update it to use "new
JdbCommand(...)").
If the fix will require "simple prompt" reply, I'd make it JdbCommand
property (like JdbCommand.allowExit)
--alex
>
> Chris
>>
>>
>> In Jdb.java you allow the waiting for the simple prompt.
>> I don't see waitForSimplePrompt used in any existing tests.
>> Since it is only looking for a single character it could
>> produce false positives if the '>' was produced in the
>> output stream. Is this wait paired to the added prompt for the
>> break point event?
>>
>> 236 return waitForSimplePrompt ? waitForSimplePrompt(1,
>> cmd.allowExit) : waitForPrompt(1, cmd.allowExit);
>>
>> It might be a good idea to include a test with multiple
>> threads each with a breakpoint that will trigger SUSPEND_EVENT_THREAD
>> behavior.
>>
>> On 10/4/18, 12:29 AM, Daniil Titov wrote:
>>> Please review the changes that fix the deadlock in the debugger when
>>> the debugger is running with the tracing option on.
>>>
>>> The problem here is that when the tracing is on the "JDI Target VM
>>> Interface" thread (the thread that reads all replies and then
>>> notifies the thread that sent the request that the reply has been
>>> received) is waiting for a lock which is already acquired by the
>>> thread that sent the request and is waiting for reply.
>>>
>>> The fix itself is in
>>> src/jdk.jdi/share/classes/com/sun/tools/jdi/VMState.java.
>>>
>>> The patch also reverts the changes done in 8129348 "Debugger hangs in
>>> trace mode with TRACE_SENDS" in
>>> src/jdk.jdi/share/classes/com/sun/tools/jdi/InvokableTypeImpl.java
>>> since they address only a specific case (VM is suspended and static
>>> method is invoked) while the proposed fix also solves issue 8129348
>>> as well as issue 8193801 "Debugger hangs in trace mode for non-static
>>> methods".
>>>
>>> The changes include new tests for issues 8193879, 8193801 and 8129348.
>>>
>>> The changes in
>>> src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java
>>> solve the problem that the prompt is not printed in the debugger
>>> output when the breakpoint is hit and the suspend policy is
>>> SUSPEND_EVENT_THREAD. This is required for new tests to detect that
>>> command "stop thread at ..." is completed.
>>>
>>> Mach5 build and jdk_jdi tests succeeded.
>>>
>>> Webrev: http://cr.openjdk.java.net/~dtitov/8193879/webrev.01/
>>> Issue: https://bugs.openjdk.java.net/browse/JDK-8193879
>>>
>>> Thanks,
>>> --Daniil
>>>
>>>
>>>
>>
>
More information about the serviceability-dev
mailing list