jdk/test/com/sun/jdi/JITDebug.java
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 /*
       
     2  * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
       
    21  * have any questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  *  Note 1: JITDebug.java is no longer a standalone regression test,
       
    26  *  due to chronic test failures on win32 platforms.  When testing,
       
    27  *  use the wrapper script (JITDebug.sh) instead, which will in turn
       
    28  *  invoke this program.
       
    29  *
       
    30  *  The problems are related to inconsistent use of "SystemRoot"
       
    31  *  versus "SYSTEMROOT" environment variables in different win32 O/S
       
    32  *  installations.  Refer to the Comments and Evaluation on bugs
       
    33  *  4522770 and 4461673 for more information.
       
    34  *
       
    35  *  Undefined SystemRoot in a win32 environment causes the O/S socket()
       
    36  *  layer to fail with WSAEPROVIDERFAILEDINIT.  The workaround used by
       
    37  *  JITDebug.sh and JITDebug.java is to select the dt_shmem transport
       
    38  *  on any win32 platform where SystemRoot is not found.
       
    39  *
       
    40  *  Note 2: What seems to be an excessive use of System.xxx.flush();
       
    41  *  is actually necessary to combat lost output on win32 systems.
       
    42  *
       
    43  *  @t e s t
       
    44  *  @bug 4291701 4376819 4422312 4522770
       
    45  *  @summary Test JIT debugging -
       
    46  *  assure that launching on uncaught exception works
       
    47  *
       
    48  *  @author Robert Field
       
    49  *  @run main/othervm JITDebug
       
    50  */
       
    51 
       
    52 import com.sun.jdi.*;
       
    53 import com.sun.jdi.connect.*;
       
    54 import java.util.*;
       
    55 import java.io.*;
       
    56 
       
    57 /*
       
    58  * This class implements three separate small programs, each
       
    59  * of which (directly or indirectly) invokes the next.  These
       
    60  * programs are:
       
    61  *    test launcher -
       
    62  *        Runs the debug target.  It exists to work around a
       
    63  *        bug in the test tools which do not allow quoted spaces
       
    64  *        in command lines.  It launchs the debug target in
       
    65  *        such a way that when it encounters an uncaught exception
       
    66  *        it (in turn) will launch the trivial debugger.
       
    67  *    debug target -
       
    68  *        A one line program which throws an uncaught exception.
       
    69  *    trivial debugger -
       
    70  *        A debugger which attachs to the debug target and shuts
       
    71  *        it down with a zero exit code.
       
    72  * These programs are differentiated by their command line arguments:
       
    73  *    test launcher - (no args)
       
    74  *    debug target - ("TARGET")
       
    75  *    trivial debugger - ("DEBUGGER", host and port)
       
    76  */
       
    77 public class JITDebug {
       
    78 
       
    79     public static void main(String[] args) {
       
    80         if (!new JITDebug().parseArgs(args)) {
       
    81             throw new RuntimeException("Unexpected command line arguments: "
       
    82                                        + args);
       
    83         }
       
    84     }
       
    85 
       
    86     boolean parseArgs(String[] args) {
       
    87         switch (args.length) {
       
    88         case 0:
       
    89             testLaunch();
       
    90             return true;
       
    91         case 1:
       
    92             if (args[0].equals("TARGET")) {
       
    93                 debugTarget();
       
    94                 return true;
       
    95             } else {
       
    96                 return false;
       
    97             }
       
    98         case 3:
       
    99             if (args[0].equals("DEBUGGER")) {
       
   100                 trivialDebugger(args[2]);
       
   101                 return true;
       
   102             } else {
       
   103                 return false;
       
   104             }
       
   105         default:
       
   106             return false;
       
   107         }
       
   108     }
       
   109 
       
   110     void testLaunch() {
       
   111         class DisplayOutput extends Thread {
       
   112             InputStream in;
       
   113 
       
   114             DisplayOutput(InputStream in) {
       
   115                 this.in = in;
       
   116             }
       
   117 
       
   118             public void run() {
       
   119                 try {
       
   120                     transfer();
       
   121                 } catch (IOException exc) {
       
   122                     new RuntimeException("Unexpected exception: " + exc);
       
   123                 }
       
   124             }
       
   125 
       
   126             void transfer() throws IOException {
       
   127                 int ch;
       
   128                 while ((ch = in.read()) != -1) {
       
   129                     System.out.print((char)ch);
       
   130                 }
       
   131                 in.close();
       
   132             }
       
   133         }
       
   134         String transportMethod = System.getProperty("TRANSPORT_METHOD");
       
   135         if (transportMethod == null) {
       
   136             transportMethod = "dt_socket"; //Default to socket transport.
       
   137         }
       
   138         String javaExe = System.getProperty("java.home") +
       
   139                          File.separator + "bin" + File.separator +"java";
       
   140         List largs = new ArrayList();
       
   141         largs.add(javaExe);
       
   142         largs.add("-agentlib:jdwp=transport=" + transportMethod + ",server=y,onuncaught=y," +
       
   143                   "launch=" +
       
   144                   javaExe + " -DTRANSPORT_METHOD=" + transportMethod + " " +
       
   145                   this.getClass().getName() + " DEBUGGER ");
       
   146         largs.add("JITDebug");
       
   147         largs.add("TARGET");
       
   148         System.out.println("Launching: " + largs);
       
   149         String[] sargs = (String[])largs.toArray(new String[largs.size()]);
       
   150         Runtime rt = Runtime.getRuntime();
       
   151         try {
       
   152             Process proc = rt.exec(VMConnection.insertDebuggeeVMOptions(sargs));
       
   153             DisplayOutput inThread = new DisplayOutput(proc.getInputStream());
       
   154             DisplayOutput erThread = new DisplayOutput(proc.getErrorStream());
       
   155             inThread.start();  // transfer all in&err
       
   156             erThread.start();
       
   157             inThread.join();  // make sure they are done
       
   158             erThread.join();
       
   159             int exitValue = proc.waitFor();
       
   160             if (exitValue != 0) {
       
   161                 throw new RuntimeException("Failure exit status: " +
       
   162                                            exitValue);
       
   163             }
       
   164         } catch (Exception exc) {
       
   165             throw new RuntimeException("Unexpected exception: " + exc);
       
   166         }
       
   167         System.out.println("JIT Debugging test PASSED");
       
   168     }
       
   169 
       
   170     void displayOutput(InputStream in) throws IOException {
       
   171 
       
   172     }
       
   173 
       
   174 
       
   175     // Target VM code
       
   176     void debugTarget() {
       
   177         System.out.flush();
       
   178         System.out.println("trigger onuncaught launch");
       
   179         System.out.flush();
       
   180         throw new RuntimeException("Start-up onuncaught handling");
       
   181     }
       
   182 
       
   183     void trivialDebugger(String transportAddress) {
       
   184         System.out.println("trivial debugger started");
       
   185         String transportMethod = System.getProperty("TRANSPORT_METHOD");
       
   186         String connectorName = null;
       
   187         if ("dt_shmem".equals(transportMethod)) {
       
   188             connectorName = "com.sun.jdi.SharedMemoryAttach";
       
   189         } else if ("dt_socket".equals(transportMethod)) {
       
   190             connectorName = "com.sun.jdi.SocketAttach";
       
   191         } else {
       
   192             System.err.flush();
       
   193             System.err.println("Unknown transportMethod: " + transportMethod + " - hanging");
       
   194             System.err.flush();
       
   195             hang();
       
   196         }
       
   197         List conns = Bootstrap.virtualMachineManager().attachingConnectors();
       
   198         for (Iterator it = conns.iterator(); it.hasNext(); ) {
       
   199             AttachingConnector conn = (AttachingConnector)it.next();
       
   200             if (conn.name().equals(connectorName)) {
       
   201                 doAttach(connectorName, conn, transportAddress);
       
   202                 return;
       
   203             }
       
   204         }
       
   205         System.err.flush();
       
   206         System.err.println("No attaching connector matching: " + connectorName + " - hanging");
       
   207         System.err.flush();
       
   208         hang();
       
   209     }
       
   210 
       
   211     void doAttach(String connectorName, AttachingConnector conn, String transportAddress) {
       
   212         Map connArgs = conn.defaultArguments();
       
   213         if ("com.sun.jdi.SharedMemoryAttach".equals(connectorName)) {
       
   214             Connector.Argument portArg = (Connector.Argument)connArgs.get("name");
       
   215             portArg.setValue(transportAddress);
       
   216         } else {
       
   217             Connector.Argument portArg = (Connector.Argument)connArgs.get("port");
       
   218             portArg.setValue(transportAddress);
       
   219         }
       
   220         try {
       
   221             VirtualMachine vm = conn.attach(connArgs);
       
   222             System.out.println("attached to: " + transportAddress);
       
   223             vm.exit(0); // we are happy - terminate VM with no error
       
   224             System.out.println("we are happy - terminated VM with no error");
       
   225         } catch (Exception exc) {
       
   226             System.err.flush();
       
   227             System.err.println("Exception: " + exc + " - hanging");
       
   228             System.err.flush();
       
   229             hang();
       
   230         }
       
   231     }
       
   232 
       
   233     /** Hang so that test fails */
       
   234     void hang() {
       
   235         try {
       
   236             // ten minute nap
       
   237             Thread.currentThread().sleep(10 * 60 * 1000);
       
   238         } catch (InterruptedException exc) {
       
   239             // shouldn't happen
       
   240         }
       
   241     }
       
   242 }