--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/JITDebug.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,242 @@
+/*
+ * Copyright 1999-2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * Note 1: JITDebug.java is no longer a standalone regression test,
+ * due to chronic test failures on win32 platforms. When testing,
+ * use the wrapper script (JITDebug.sh) instead, which will in turn
+ * invoke this program.
+ *
+ * The problems are related to inconsistent use of "SystemRoot"
+ * versus "SYSTEMROOT" environment variables in different win32 O/S
+ * installations. Refer to the Comments and Evaluation on bugs
+ * 4522770 and 4461673 for more information.
+ *
+ * Undefined SystemRoot in a win32 environment causes the O/S socket()
+ * layer to fail with WSAEPROVIDERFAILEDINIT. The workaround used by
+ * JITDebug.sh and JITDebug.java is to select the dt_shmem transport
+ * on any win32 platform where SystemRoot is not found.
+ *
+ * Note 2: What seems to be an excessive use of System.xxx.flush();
+ * is actually necessary to combat lost output on win32 systems.
+ *
+ * @t e s t
+ * @bug 4291701 4376819 4422312 4522770
+ * @summary Test JIT debugging -
+ * assure that launching on uncaught exception works
+ *
+ * @author Robert Field
+ * @run main/othervm JITDebug
+ */
+
+import com.sun.jdi.*;
+import com.sun.jdi.connect.*;
+import java.util.*;
+import java.io.*;
+
+/*
+ * This class implements three separate small programs, each
+ * of which (directly or indirectly) invokes the next. These
+ * programs are:
+ * test launcher -
+ * Runs the debug target. It exists to work around a
+ * bug in the test tools which do not allow quoted spaces
+ * in command lines. It launchs the debug target in
+ * such a way that when it encounters an uncaught exception
+ * it (in turn) will launch the trivial debugger.
+ * debug target -
+ * A one line program which throws an uncaught exception.
+ * trivial debugger -
+ * A debugger which attachs to the debug target and shuts
+ * it down with a zero exit code.
+ * These programs are differentiated by their command line arguments:
+ * test launcher - (no args)
+ * debug target - ("TARGET")
+ * trivial debugger - ("DEBUGGER", host and port)
+ */
+public class JITDebug {
+
+ public static void main(String[] args) {
+ if (!new JITDebug().parseArgs(args)) {
+ throw new RuntimeException("Unexpected command line arguments: "
+ + args);
+ }
+ }
+
+ boolean parseArgs(String[] args) {
+ switch (args.length) {
+ case 0:
+ testLaunch();
+ return true;
+ case 1:
+ if (args[0].equals("TARGET")) {
+ debugTarget();
+ return true;
+ } else {
+ return false;
+ }
+ case 3:
+ if (args[0].equals("DEBUGGER")) {
+ trivialDebugger(args[2]);
+ return true;
+ } else {
+ return false;
+ }
+ default:
+ return false;
+ }
+ }
+
+ void testLaunch() {
+ class DisplayOutput extends Thread {
+ InputStream in;
+
+ DisplayOutput(InputStream in) {
+ this.in = in;
+ }
+
+ public void run() {
+ try {
+ transfer();
+ } catch (IOException exc) {
+ new RuntimeException("Unexpected exception: " + exc);
+ }
+ }
+
+ void transfer() throws IOException {
+ int ch;
+ while ((ch = in.read()) != -1) {
+ System.out.print((char)ch);
+ }
+ in.close();
+ }
+ }
+ String transportMethod = System.getProperty("TRANSPORT_METHOD");
+ if (transportMethod == null) {
+ transportMethod = "dt_socket"; //Default to socket transport.
+ }
+ String javaExe = System.getProperty("java.home") +
+ File.separator + "bin" + File.separator +"java";
+ List largs = new ArrayList();
+ largs.add(javaExe);
+ largs.add("-agentlib:jdwp=transport=" + transportMethod + ",server=y,onuncaught=y," +
+ "launch=" +
+ javaExe + " -DTRANSPORT_METHOD=" + transportMethod + " " +
+ this.getClass().getName() + " DEBUGGER ");
+ largs.add("JITDebug");
+ largs.add("TARGET");
+ System.out.println("Launching: " + largs);
+ String[] sargs = (String[])largs.toArray(new String[largs.size()]);
+ Runtime rt = Runtime.getRuntime();
+ try {
+ Process proc = rt.exec(VMConnection.insertDebuggeeVMOptions(sargs));
+ DisplayOutput inThread = new DisplayOutput(proc.getInputStream());
+ DisplayOutput erThread = new DisplayOutput(proc.getErrorStream());
+ inThread.start(); // transfer all in&err
+ erThread.start();
+ inThread.join(); // make sure they are done
+ erThread.join();
+ int exitValue = proc.waitFor();
+ if (exitValue != 0) {
+ throw new RuntimeException("Failure exit status: " +
+ exitValue);
+ }
+ } catch (Exception exc) {
+ throw new RuntimeException("Unexpected exception: " + exc);
+ }
+ System.out.println("JIT Debugging test PASSED");
+ }
+
+ void displayOutput(InputStream in) throws IOException {
+
+ }
+
+
+ // Target VM code
+ void debugTarget() {
+ System.out.flush();
+ System.out.println("trigger onuncaught launch");
+ System.out.flush();
+ throw new RuntimeException("Start-up onuncaught handling");
+ }
+
+ void trivialDebugger(String transportAddress) {
+ System.out.println("trivial debugger started");
+ String transportMethod = System.getProperty("TRANSPORT_METHOD");
+ String connectorName = null;
+ if ("dt_shmem".equals(transportMethod)) {
+ connectorName = "com.sun.jdi.SharedMemoryAttach";
+ } else if ("dt_socket".equals(transportMethod)) {
+ connectorName = "com.sun.jdi.SocketAttach";
+ } else {
+ System.err.flush();
+ System.err.println("Unknown transportMethod: " + transportMethod + " - hanging");
+ System.err.flush();
+ hang();
+ }
+ List conns = Bootstrap.virtualMachineManager().attachingConnectors();
+ for (Iterator it = conns.iterator(); it.hasNext(); ) {
+ AttachingConnector conn = (AttachingConnector)it.next();
+ if (conn.name().equals(connectorName)) {
+ doAttach(connectorName, conn, transportAddress);
+ return;
+ }
+ }
+ System.err.flush();
+ System.err.println("No attaching connector matching: " + connectorName + " - hanging");
+ System.err.flush();
+ hang();
+ }
+
+ void doAttach(String connectorName, AttachingConnector conn, String transportAddress) {
+ Map connArgs = conn.defaultArguments();
+ if ("com.sun.jdi.SharedMemoryAttach".equals(connectorName)) {
+ Connector.Argument portArg = (Connector.Argument)connArgs.get("name");
+ portArg.setValue(transportAddress);
+ } else {
+ Connector.Argument portArg = (Connector.Argument)connArgs.get("port");
+ portArg.setValue(transportAddress);
+ }
+ try {
+ VirtualMachine vm = conn.attach(connArgs);
+ System.out.println("attached to: " + transportAddress);
+ vm.exit(0); // we are happy - terminate VM with no error
+ System.out.println("we are happy - terminated VM with no error");
+ } catch (Exception exc) {
+ System.err.flush();
+ System.err.println("Exception: " + exc + " - hanging");
+ System.err.flush();
+ hang();
+ }
+ }
+
+ /** Hang so that test fails */
+ void hang() {
+ try {
+ // ten minute nap
+ Thread.currentThread().sleep(10 * 60 * 1000);
+ } catch (InterruptedException exc) {
+ // shouldn't happen
+ }
+ }
+}