0N/A/*
2362N/A * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A/*
0N/A * Note 1: JITDebug.java is no longer a standalone regression test,
0N/A * due to chronic test failures on win32 platforms. When testing,
0N/A * use the wrapper script (JITDebug.sh) instead, which will in turn
0N/A * invoke this program.
0N/A *
0N/A * The problems are related to inconsistent use of "SystemRoot"
0N/A * versus "SYSTEMROOT" environment variables in different win32 O/S
0N/A * installations. Refer to the Comments and Evaluation on bugs
0N/A * 4522770 and 4461673 for more information.
0N/A *
0N/A * Undefined SystemRoot in a win32 environment causes the O/S socket()
0N/A * layer to fail with WSAEPROVIDERFAILEDINIT. The workaround used by
0N/A * JITDebug.sh and JITDebug.java is to select the dt_shmem transport
0N/A * on any win32 platform where SystemRoot is not found.
0N/A *
0N/A * Note 2: What seems to be an excessive use of System.xxx.flush();
0N/A * is actually necessary to combat lost output on win32 systems.
0N/A *
0N/A * @t e s t
0N/A * @bug 4291701 4376819 4422312 4522770
0N/A * @summary Test JIT debugging -
0N/A * assure that launching on uncaught exception works
0N/A *
0N/A * @author Robert Field
0N/A * @run main/othervm JITDebug
0N/A */
0N/A
0N/Aimport com.sun.jdi.*;
0N/Aimport com.sun.jdi.connect.*;
0N/Aimport java.util.*;
0N/Aimport java.io.*;
0N/A
0N/A/*
0N/A * This class implements three separate small programs, each
0N/A * of which (directly or indirectly) invokes the next. These
0N/A * programs are:
0N/A * test launcher -
0N/A * Runs the debug target. It exists to work around a
0N/A * bug in the test tools which do not allow quoted spaces
0N/A * in command lines. It launchs the debug target in
0N/A * such a way that when it encounters an uncaught exception
0N/A * it (in turn) will launch the trivial debugger.
0N/A * debug target -
0N/A * A one line program which throws an uncaught exception.
0N/A * trivial debugger -
0N/A * A debugger which attachs to the debug target and shuts
0N/A * it down with a zero exit code.
0N/A * These programs are differentiated by their command line arguments:
0N/A * test launcher - (no args)
0N/A * debug target - ("TARGET")
0N/A * trivial debugger - ("DEBUGGER", host and port)
0N/A */
0N/Apublic class JITDebug {
0N/A
0N/A public static void main(String[] args) {
0N/A if (!new JITDebug().parseArgs(args)) {
0N/A throw new RuntimeException("Unexpected command line arguments: "
0N/A + args);
0N/A }
0N/A }
0N/A
0N/A boolean parseArgs(String[] args) {
0N/A switch (args.length) {
0N/A case 0:
0N/A testLaunch();
0N/A return true;
0N/A case 1:
0N/A if (args[0].equals("TARGET")) {
0N/A debugTarget();
0N/A return true;
0N/A } else {
0N/A return false;
0N/A }
0N/A case 3:
0N/A if (args[0].equals("DEBUGGER")) {
0N/A trivialDebugger(args[2]);
0N/A return true;
0N/A } else {
0N/A return false;
0N/A }
0N/A default:
0N/A return false;
0N/A }
0N/A }
0N/A
0N/A void testLaunch() {
0N/A class DisplayOutput extends Thread {
0N/A InputStream in;
0N/A
0N/A DisplayOutput(InputStream in) {
0N/A this.in = in;
0N/A }
0N/A
0N/A public void run() {
0N/A try {
0N/A transfer();
0N/A } catch (IOException exc) {
0N/A new RuntimeException("Unexpected exception: " + exc);
0N/A }
0N/A }
0N/A
0N/A void transfer() throws IOException {
0N/A int ch;
0N/A while ((ch = in.read()) != -1) {
0N/A System.out.print((char)ch);
0N/A }
0N/A in.close();
0N/A }
0N/A }
0N/A String transportMethod = System.getProperty("TRANSPORT_METHOD");
0N/A if (transportMethod == null) {
0N/A transportMethod = "dt_socket"; //Default to socket transport.
0N/A }
0N/A String javaExe = System.getProperty("java.home") +
0N/A File.separator + "bin" + File.separator +"java";
0N/A List largs = new ArrayList();
0N/A largs.add(javaExe);
0N/A largs.add("-agentlib:jdwp=transport=" + transportMethod + ",server=y,onuncaught=y," +
0N/A "launch=" +
0N/A javaExe + " -DTRANSPORT_METHOD=" + transportMethod + " " +
0N/A this.getClass().getName() + " DEBUGGER ");
0N/A largs.add("JITDebug");
0N/A largs.add("TARGET");
0N/A System.out.println("Launching: " + largs);
0N/A String[] sargs = (String[])largs.toArray(new String[largs.size()]);
0N/A Runtime rt = Runtime.getRuntime();
0N/A try {
0N/A Process proc = rt.exec(VMConnection.insertDebuggeeVMOptions(sargs));
0N/A DisplayOutput inThread = new DisplayOutput(proc.getInputStream());
0N/A DisplayOutput erThread = new DisplayOutput(proc.getErrorStream());
0N/A inThread.start(); // transfer all in&err
0N/A erThread.start();
0N/A inThread.join(); // make sure they are done
0N/A erThread.join();
0N/A int exitValue = proc.waitFor();
0N/A if (exitValue != 0) {
0N/A throw new RuntimeException("Failure exit status: " +
0N/A exitValue);
0N/A }
0N/A } catch (Exception exc) {
0N/A throw new RuntimeException("Unexpected exception: " + exc);
0N/A }
0N/A System.out.println("JIT Debugging test PASSED");
0N/A }
0N/A
0N/A void displayOutput(InputStream in) throws IOException {
0N/A
0N/A }
0N/A
0N/A
0N/A // Target VM code
0N/A void debugTarget() {
0N/A System.out.flush();
0N/A System.out.println("trigger onuncaught launch");
0N/A System.out.flush();
0N/A throw new RuntimeException("Start-up onuncaught handling");
0N/A }
0N/A
0N/A void trivialDebugger(String transportAddress) {
0N/A System.out.println("trivial debugger started");
0N/A String transportMethod = System.getProperty("TRANSPORT_METHOD");
0N/A String connectorName = null;
0N/A if ("dt_shmem".equals(transportMethod)) {
0N/A connectorName = "com.sun.jdi.SharedMemoryAttach";
0N/A } else if ("dt_socket".equals(transportMethod)) {
0N/A connectorName = "com.sun.jdi.SocketAttach";
0N/A } else {
0N/A System.err.flush();
0N/A System.err.println("Unknown transportMethod: " + transportMethod + " - hanging");
0N/A System.err.flush();
0N/A hang();
0N/A }
0N/A List conns = Bootstrap.virtualMachineManager().attachingConnectors();
0N/A for (Iterator it = conns.iterator(); it.hasNext(); ) {
0N/A AttachingConnector conn = (AttachingConnector)it.next();
0N/A if (conn.name().equals(connectorName)) {
0N/A doAttach(connectorName, conn, transportAddress);
0N/A return;
0N/A }
0N/A }
0N/A System.err.flush();
0N/A System.err.println("No attaching connector matching: " + connectorName + " - hanging");
0N/A System.err.flush();
0N/A hang();
0N/A }
0N/A
0N/A void doAttach(String connectorName, AttachingConnector conn, String transportAddress) {
0N/A Map connArgs = conn.defaultArguments();
0N/A if ("com.sun.jdi.SharedMemoryAttach".equals(connectorName)) {
0N/A Connector.Argument portArg = (Connector.Argument)connArgs.get("name");
0N/A portArg.setValue(transportAddress);
0N/A } else {
0N/A Connector.Argument portArg = (Connector.Argument)connArgs.get("port");
0N/A portArg.setValue(transportAddress);
0N/A }
0N/A try {
0N/A VirtualMachine vm = conn.attach(connArgs);
0N/A System.out.println("attached to: " + transportAddress);
0N/A vm.exit(0); // we are happy - terminate VM with no error
0N/A System.out.println("we are happy - terminated VM with no error");
0N/A } catch (Exception exc) {
0N/A System.err.flush();
0N/A System.err.println("Exception: " + exc + " - hanging");
0N/A System.err.flush();
0N/A hang();
0N/A }
0N/A }
0N/A
0N/A /** Hang so that test fails */
0N/A void hang() {
0N/A try {
0N/A // ten minute nap
0N/A Thread.currentThread().sleep(10 * 60 * 1000);
0N/A } catch (InterruptedException exc) {
0N/A // shouldn't happen
0N/A }
0N/A }
0N/A}