-
Bug
-
Resolution: Won't Fix
-
P3
-
8u60, 11, 12
-
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 ----------
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 ----------