8193150: Create a jtreg version of the test from JDK-8187143.
Summary: Create a new jtreg test based on the test attached to the bug and add it to the ProblemsList.
Reviewed-by: sspitsyn, cjplummer
--- a/test/jdk/ProblemList.txt Fri Feb 09 08:23:42 2018 -0500
+++ b/test/jdk/ProblemList.txt Fri Feb 09 09:56:05 2018 -0800
@@ -481,6 +481,8 @@
com/sun/jdi/sde/SourceDebugExtensionTest.java 8158066 windows-all
+com/sun/jdi/NashornPopFrameTest.java 8187143 generic-all
+
############################################################################
# jdk_time
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/NashornPopFrameTest.java Fri Feb 09 09:56:05 2018 -0800
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8187143
+ * @summary JDI crash in ~BufferBlob::MethodHandles adapters
+ *
+ * @run build TestScaffold VMConnection TargetListener TargetAdapter
+ * @run compile -g NashornPopFrameTest.java
+ * @run driver NashornPopFrameTest
+ */
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+import javax.script.*;
+
+import java.io.PrintStream;
+
+
+// The debuggee, creates and uses a Nashorn engine to evaluate a simple script.
+
+// The debugger tries to set a breakpoint in Nashorn internal DEBUGGER method.
+// When the breakpoint is reached, it looks for stack frame whose method's
+// declaring type name starts with jdk.nashorn.internal.scripts.Script$.
+// (nashorn dynamically generated classes)
+// It then pops stack frames using the ThreadReference.popFrames() call, up to
+// and including the above stackframe.
+// The execution of the debuggee application is resumed after the needed
+// frames have been popped.
+
+class ScriptDebuggee {
+ public final static int BKPT_LINE = 74;
+ static ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
+ static public String failReason = null;
+
+ static void doit() throws Exception {
+ System.out.println("Debugee: started!");
+ String script =
+ "function f() {\r\n" +
+ " debugger;\r\n" +
+ " debugger;\r\n" +
+ "}\r\n" +
+ "f();";
+ try {
+ engine.eval(script);
+ } catch (Exception ex) {
+ failReason = "ScriptDebuggee failed: Exception in engine.eval(): "
+ + ex.toString();
+ ex.printStackTrace();
+ }
+ System.out.println("Debugee: finished!"); // BKPT_LINE
+ }
+
+ public static void main(String[] args) throws Exception {
+ doit();
+ }
+}
+
+/********** test program **********/
+
+public class NashornPopFrameTest extends TestScaffold {
+ static PrintStream out = System.out;
+ static boolean breakpointReached = false;
+ String debuggeeFailReason = null;
+ ClassType targetClass;
+ ThreadReference mainThread;
+ BreakpointRequest bkptRequest;
+
+ NashornPopFrameTest(String args[]) {
+ super(args);
+ }
+
+ public static void main(String[] args) throws Exception {
+ NashornPopFrameTest nashornPopFrameTest = new NashornPopFrameTest(args);
+ nashornPopFrameTest.startTests();
+ }
+
+ /********** test core **********/
+
+ protected void runTests() throws Exception {
+ /*
+ * Get to the top of main() to determine targetClass and mainThread
+ */
+ BreakpointEvent bpe = startToMain("ScriptDebuggee");
+ targetClass = (ClassType)bpe.location().declaringType();
+ out.println("Agent: runTests: after startToMain()");
+
+ mainThread = bpe.thread();
+ EventRequestManager erm = vm().eventRequestManager();
+
+ Location loc = findLocation(targetClass, ScriptDebuggee.BKPT_LINE);
+
+ try {
+ addListener(this);
+ } catch (Exception ex){
+ ex.printStackTrace();
+ failure("Failed: Could not add listener");
+ throw new Exception("NashornPopFrameTest: failed with Exception in AddListener");
+ }
+
+ pauseAtDebugger(vm());
+ bkptRequest = erm.createBreakpointRequest(loc);
+ bkptRequest.enable();
+
+ vm().resume();
+
+ try {
+ listen(vm());
+ } catch (Exception exp) {
+ exp.printStackTrace();
+ failure("Failed: Caught Exception while Listening");
+ throw new Exception("NashornPopFrameTest: failed with Exception in listen()");
+ }
+
+ // Debugger continues to run until it receives a VMdisconnect event either because
+ // the Debuggee crashed / got exception / finished successfully.
+ while (!vmDisconnected) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException ee) {
+ }
+ }
+
+ removeListener(this);
+
+ if (breakpointReached) {
+ if (debuggeeFailReason != null) {
+ failure(debuggeeFailReason);
+ }
+ } else {
+ failure("Expected breakpoint in ScriptDebuggee:" +
+ ScriptDebuggee.BKPT_LINE + " was not reached");
+ }
+ if (testFailed) {
+ throw new Exception("NashornPopFrameTest: failed");
+ }
+ out.println("NashornPopFrameTest: passed");
+ }
+
+ private static void pauseAtDebugger(VirtualMachine vm) throws AbsentInformationException {
+ for (ReferenceType t : vm.allClasses()) pauseAtDebugger(t);
+ }
+
+ // Set a breakpoint in Nashorn internal DEBUGGER method.
+ private static void pauseAtDebugger(ReferenceType t) throws AbsentInformationException {
+ if (!t.name().endsWith(".ScriptRuntime")) {
+ return;
+ }
+ for (Location l : t.allLineLocations()) {
+ if (!l.method().name().equals("DEBUGGER")) continue;
+ BreakpointRequest bkptReq = t.virtualMachine().eventRequestManager().createBreakpointRequest(l);
+ out.println("Setting breakpoint for " + l);
+ bkptReq.enable();
+ break;
+ }
+ }
+
+ private static void listen(VirtualMachine vm) throws Exception {
+ EventQueue eventQueue = vm.eventQueue();
+ EventSet es = eventQueue.remove();
+ if (es != null) {
+ handle(es);
+ }
+ }
+
+ // Handle event when breakpoint is reached
+ private static void handle(EventSet eventSet) throws Exception {
+ out.println("Agent handle(): started");
+ for (Event event : eventSet) {
+ if (event instanceof BreakpointEvent) {
+ findFrameAndPop(event);
+ }
+ }
+ eventSet.resume();
+ out.println("Agent handle(): finished");
+ }
+
+ private static void findFrameAndPop(Event event) throws Exception {
+ ThreadReference thread = ((BreakpointEvent) event).thread();
+ out.println("Agent: handling Breakpoint " + " at " +
+ ((BreakpointEvent) event).location() +
+ " in thread: " + thread);
+ StackFrame sf = findScriptFrame(thread);
+ if (sf != null) {
+ out.println("Thread Pop Frame on StackFrame = " + sf);
+ thread.popFrames(sf);
+ }
+ }
+
+ // Find stack frame whose method's declaring type name starts with
+ // jdk.nashorn.internal.scripts.Script$ and return that frame
+ private static StackFrame findScriptFrame(ThreadReference t) throws IncompatibleThreadStateException {
+ for (int i = 0; i < t.frameCount(); i++) {
+ StackFrame sf = t.frame(i);
+ String typeName = sf.location().method().declaringType().name();
+ if (typeName.startsWith("jdk.nashorn.internal.scripts.Script$")) {
+ out.println("Agent: in findScriptFrame: TypeName = " + typeName);
+ return sf;
+ }
+ }
+ throw new RuntimeException("no script frame");
+ }
+
+ static int bkptCount = 0;
+
+ /********** event handlers **********/
+
+ public void breakpointReached(BreakpointEvent event) {
+ ThreadReference thread = ((BreakpointEvent) event).thread();
+ String locStr = "" + ((BreakpointEvent) event).location();
+ out.println("Agent: BreakpointEvent #" + (bkptCount++) +
+ " at " + locStr + " in thread: " + thread);
+ if (locStr.equals("ScriptDebuggee:" + ScriptDebuggee.BKPT_LINE)) {
+ breakpointReached = true;
+ Field failReasonField = targetClass.fieldByName("failReason");
+ Value failReasonVal = targetClass.getValue(failReasonField);
+ if (failReasonVal != null) {
+ debuggeeFailReason = ((StringReference)failReasonVal).value();
+ }
+ bkptRequest.disable();
+ }
+ }
+
+ public void eventSetComplete(EventSet set) {
+ set.resume();
+ }
+
+ public void vmDisconnected(VMDisconnectEvent event) {
+ println("Agent: Got VMDisconnectEvent");
+ }
+
+}