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