Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8352759

TestScaffold resumes threads too early when using multiple event listeners

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P4 P4
    • tbd
    • 25
    • core-svc

      TestScaffold allows you to add event listeners. For any given event, each listener's event callback for that event will be called. For example, breakpointReached() or classPrepared(). Since there can be more than one listener registered, there may be more than one callback made for any given event.

      This approach is problematic w.r.t. the suspend policy. If the event thread or all threads are suspended, they will be resumed after the first listener's callback is made. This can lead to unexpected test behaviour if the test is counting on threads to remain suspended until the last callback is made. For example, a test may want to setup a breakpoint after a ClassPrepareEvent is received, but if there are two listeners registered and the 2nd one sets up the breakpoint, by the time the breakpoint is setup the debuggee may have already resumed and executed past it.

      What makes the secenario more likely is that APIs like listenUntilVMDisconnect() and resumeToPrepareOf() register listeners. That means it is bascially not possible for the test itself to also have a listener registered while calling one of these methods.

      I ran into this problem when I setup a ClassPrepareRequest after having received the first ThreadStartEvent. The test then did a listenUntilVMDisconnect(). When the first ClassPrepareEvent arrived, the handler tried to call ThreadGroupReference.groups(), but it sometimes got a VMDisconnectedException. The reason is because another listener was added by listenUntilVMDisconnect(), and it was called first, and then all threads resumed after it was called.

      The issues is with the TestScaffold EventHandler class. It iterates over every Event in the EventSet, and for each event it calls the appropriate event handler method for each registered listener. The problem is that it also calls eventSetComplete() for each listener, and eventSetComplete() calls EventSet.resume(). So the first listener always resumes threads before any subsequent listeners are called. Resuming should be deferred until after the last listener is called.

            Unassigned Unassigned
            cjplummer Chris Plummer
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: