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

AbstractMethodError in Nashorn-generated code when popping stack frames via JDI

XMLWordPrintable

    • generic
    • generic

      FULL PRODUCT VERSION :
      java version "1.8.0_131"
      Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
      Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows [Version 10.0.10586]

      A DESCRIPTION OF THE PROBLEM :
      I have a debugger that connects using JDI AttachingConnector to a debugee that runs a Nashorn script over and over again.

      The debugger sets a breakpoint inside a JavaScript function.

      When the breakpoint is hit, the debugger uses ThreadReference.popFrames to pop off the current stack frame, then resumes the debugee.

      Right away, or after stopping and restarting the debugger a few times, the debugee crashes with:

      Exception in thread "main" java.lang.AbstractMethodError
              at jdk.nashorn.javaadapters.java.lang.Runnable.run(Unknown Source)
              at Debugee.main(Debugee.java:21)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      In window/console 1:

      javac Debugee.java
      java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7777 -cp . Debugee

      ========================

      In window/console 2:

      javac -cp "%JAVA_HOME%\lib\tools.jar" Debugger.java
      java -cp "%JAVA_HOME%\lib\tools.jar;." Debugger

      (Ctrl-C + re-run a few times as necessary)

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      From the debugee:

      Listening for transport dt_socket at address: 7777
      Debugee: Running
      Java: 1.8.0_131
      Runnable = jdk.nashorn.javaadapters.java.lang.Runnable@1ba9117e
      Debugee: run 0
      Debugee: run 1
      ...
      Debugee: run N
      ...ad infinitum...

      (Note that N is fixed here, since the debugger pops the stack frame over and over again, preventing the number from being incremented.)

      ========================

      From the debugger:

      Java: 1.8.0_131
      Setting breakpoint for jdk.nashorn.internal.scripts.Script$Recompilation$2$53$\^eval\_:3
      Listening for events...
      Breakpoint at jdk.nashorn.internal.scripts.Script$Recompilation$2$53$\^eval\_:3
      Breakpoint at jdk.nashorn.internal.scripts.Script$Recompilation$2$53$\^eval\_:3
      ...
      ...ad infinitum...

      ACTUAL -
      From the debugee:

      ...
      Debugee: run 20
      Debugee: run 20
      Debugee: run 20
      ERROR: transport error 202: recv error: Connection reset by peer
      Listening for transport dt_socket at address: 7777
      Debugee: run 21
      Debugee: run 22
      Exception in thread "main" java.lang.AbstractMethodError
              at jdk.nashorn.javaadapters.java.lang.Runnable.run(Unknown Source)
              at Debugee.main(Debugee.java:21)

      ========================

      From the debugger:

      ...
      Breakpoint at jdk.nashorn.internal.scripts.Script$Recompilation$2$53$\^eval\_:3
      Exception in thread "main" com.sun.jdi.VMDisconnectedException
              at com.sun.tools.jdi.EventQueueImpl.removeUnfiltered(EventQueueImpl.java:199)
              at com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:96)
              at com.sun.tools.jdi.EventQueueImpl.remove(EventQueueImpl.java:82)
              at Debugger.listen(Debugger.java:44)
              at Debugger.main(Debugger.java:23)

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      See above

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Debugee.java:

      import jdk.nashorn.api.scripting.NashornScriptEngineFactory;

      import javax.script.Invocable;
      import javax.script.ScriptEngine;

      public class Debugee {
          public static void main(String[] args) throws Exception {
              System.out.println("Debugee: Running");
              System.out.println("Java: " + System.getProperty("java.version"));

              ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
              String script = "(function() {var i=0;return { run: function target() {\r\n" + // L1
                      "print('Debugee: run ' + i);\r\n" + // L2
                      "i+=1;\r\n" + // L3
                      "} };})(this)";
              Object runObj = engine.eval(script);
              Runnable runner = ((Invocable) engine).getInterface(runObj, Runnable.class);
              System.out.println("Runnable = " + runner);

              while (true) {
                  runner.run();
                  Thread.sleep(400);
              }
          }
      }

      ====================

      Debugger.java:

      import com.sun.jdi.*;
      import com.sun.jdi.connect.*;
      import com.sun.jdi.event.*;
      import com.sun.jdi.request.BreakpointRequest;

      import java.util.List;
      import java.util.Map;

      public class Debugger {

          public static void main(String[] args) throws Exception {
              System.out.println("Java: " + System.getProperty("java.version"));
              AttachingConnector connector = getConnector();

              Map<String, Connector.Argument> cArgs = connector.defaultArguments();
              cArgs.get("port").setValue("" + 7777);
              cArgs.get("hostname").setValue("localhost");

              VirtualMachine vm = connector.attach(cArgs);
              vm.resume();

              considerReferenceTypes(vm);
              listen(vm);
              System.out.println("Done...");
          }

          private static AttachingConnector getConnector() {
              VirtualMachineManager vmm = Bootstrap.virtualMachineManager();
              AttachingConnector connector = null;
              for (AttachingConnector c : vmm.attachingConnectors()) {
                  if (c.name().equals("com.sun.jdi.SocketAttach")) {
                      connector = c;
                      break;
                  }
              }
              if (connector == null) throw new RuntimeException("no connector");
              return connector;
          }

          private static void listen(VirtualMachine vm) throws Exception {
              EventQueue eventQueue = vm.eventQueue();
              System.out.println("Listening for events...");
              while (true) {
                  EventSet es = eventQueue.remove();
                  if (es == null) break;
                  handle(es);
              }
          }

          private static void handle(EventSet eventSet) throws Exception {
              for (Event event : eventSet) {
                  if (event instanceof BreakpointEvent) {
                      Thread.sleep(100);
                      System.out.println("Breakpoint at " + ((BreakpointEvent) event).location());
                      ThreadReference thread = ((BreakpointEvent) event).thread();
                      List<StackFrame> frames = thread.frames();
                      thread.popFrames(frames.get(0));
                  }
              }
              eventSet.resume();
          }

          private static void considerReferenceTypes(VirtualMachine vm) throws AbsentInformationException {
              for (ReferenceType t : vm.allClasses()) considerReferenceType(t);
          }

          private static void considerReferenceType(ReferenceType t) throws AbsentInformationException {
              if (!t.name().contains("Script$Recompilation")) return;
              for (Location l : t.allLineLocations()) {
                  if (!l.method().name().contains("target")) continue; // see Debugee.java
                  if (l.lineNumber() < 3) continue; // see Debugee.java
                  BreakpointRequest breakpointRequest = t.virtualMachine().eventRequestManager().createBreakpointRequest(l);
                  System.out.println("Setting breakpoint for " + l);
                  breakpointRequest.enable();
                  break;
              }
          }
      }

      ---------- END SOURCE ----------

        1. Debugee.java
          0.8 kB
        2. Debugger.java
          3 kB
        3. hs_err_pid27768.log
          57 kB

            fmatte Fairoz Matte
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: