RFR: JDK-8169718: nsk/jdb/locals/locals002: ERROR: Cannot find boolVar with expected value: false
Gary Adams
gary.adams at oracle.com
Thu Jun 7 12:48:52 UTC 2018
It's theoretically possible that the corrupted output
could be produced with a single step command
because of the separate event handler and command
processing threads, although the failures that have
been recorded were all observed later in a test scenario.
So let's look at a third possible way to fix the issue.
- we need a mechanism that will protect executeCommand and handleEvent
- to ensure that neither produces a partial output
A few key snippets from the code below.
The method executeCommand() is called from both
the command processing thread and the event handler
thread. It is also called recursively, so a lock may not be
appropriate
The eventHandler output is produce incrementally
- handleEvent produces the header, e.g. "Set completed:"
- vmInterrupted() produces
printCurrentLocation()
monitor commands output (if any) by calling executeCommand()
printPrompt()
I don't have concrete fix to propose, yet, but I'm leaning towards
having executeCommand buffer it's output and return it as a single
string. It would involve a getPrompt() instead of printPrompt, so
the text could be composed. It would also require aggregating any
output that is currently sent directly to MessageOutput.
It might also be addressed by enhancing MessageOutput to
include some sort of buffering for the current event or current command.
It's unlikely this would be ready before the jdk11 repos are cloned, so
it may be best to target these bugs for the next release.
src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java:
...
209 public void vmInterrupted() {
210 Thread.yield(); // fetch output
211 printCurrentLocation();
212 for (String cmd : monitorCommands) {
213 StringTokenizer t = new StringTokenizer(cmd);
214 t.nextToken(); // get rid of monitor number
* 215 executeCommand(t);*
216 }
217 MessageOutput.printPrompt();
218 }
...
* 391 void executeCommand(StringTokenizer t) {*
392 String cmd = t.nextToken().toLowerCase();
393 // Normally, prompt for the next command after this
one is done
394 boolean showPrompt = true;
395
...
589 if (showPrompt) {
590 MessageOutput.printPrompt();
591 }
592 }
src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/EventHandler.java:
...
66 public void run() {
67 EventQueue queue = Env.vm().eventQueue();
68 while (connected) {
69 try {
70 EventSet eventSet = queue.remove();
71 boolean resumeStoppedApp = false;
72 EventIterator it = eventSet.eventIterator();
73 while (it.hasNext()) {
* 74 resumeStoppedApp |=
!handleEvent(it.nextEvent());*
75 }
76
77 if (resumeStoppedApp) {
78 eventSet.resume();
79 } else if (eventSet.suspendPolicy() ==
EventRequest.SUSPEND_ALL) {
80 setCurrentThread(eventSet);
* 81 notifier.vmInterrupted();*
82 }
83 } catch (InterruptedException exc) {
84 // Do nothing. Any changes will be seen at
top of loop.
85 } catch (VMDisconnectedException discExc) {
86 handleDisconnectedException();
87 break;
88 }
89 }
90 synchronized (this) {
91 completed = true;
92 notifyAll();
93 }
94 }
96 private boolean handleEvent(Event event) {
97 notifier.receivedEvent(event);
98
99 if (event instanceof ExceptionEvent) {
100 return exceptionEvent(event);
101 } else if (event instanceof BreakpointEvent) {
102 return breakpointEvent(event);
103 } else if (event instanceof WatchpointEvent) {
104 return fieldWatchEvent(event);
105 } else if (event instanceof StepEvent) {
106 return stepEvent(event);
107 } else if (event instanceof MethodEntryEvent) {
108 return methodEntryEvent(event);
109 } else if (event instanceof MethodExitEvent) {
110 return methodExitEvent(event);
111 } else if (event instanceof ClassPrepareEvent) {
112 return classPrepareEvent(event);
113 } else if (event instanceof ClassUnloadEvent) {
114 return classUnloadEvent(event);
115 } else if (event instanceof ThreadStartEvent) {
116 return threadStartEvent(event);
117 } else if (event instanceof ThreadDeathEvent) {
118 return threadDeathEvent(event);
119 } else if (event instanceof VMStartEvent) {
120 return vmStartEvent(event);
121 } else {
122 return handleExitEvent(event);
123 }
124 }
On 6/6/18, 3:27 PM, Chris Plummer wrote:
...
>
> The point I'm trying to get across is I don't think the issue is with
> the rate of commands being sent. I think the issue can be isolated to
> a single step command that has the first prompt appearing in the
> middle of the "Step completed: ..." output.
>
> command thread: receive and execute "step" command
> event thread: receive "step" breakpoint. print "Step completed: "
> command thread: print "main[1]"
> event thread: print text that comes after "Step completed: "
> event thread: print "main[1]"
>
> This has to be fixed in the sender of the output, not the receiver of
> the output (or the sender of the command).
>
> Chris
...
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20180607/83540176/attachment-0001.html>
More information about the serviceability-dev
mailing list