Save This Page
Home » openjdk-7 » com.sun.tools.example » trace » [javadoc | source]
    1   /*
    2    * Copyright (c) 2001, Oracle and/or its affiliates. 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.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package com.sun.tools.example.trace;
   27   
   28   import com.sun.jdi.VirtualMachine;
   29   import com.sun.jdi.Bootstrap;
   30   import com.sun.jdi.connect;
   31   
   32   import java.util.Map;
   33   import java.util.List;
   34   
   35   import java.io.PrintWriter;
   36   import java.io.FileWriter;
   37   import java.io.IOException;
   38   
   39   /**
   40    * This program traces the execution of another program.
   41    * See "java Trace -help".
   42    * It is a simple example of the use of the Java Debug Interface.
   43    *
   44    * @author Robert Field
   45    */
   46   public class Trace {
   47   
   48       // Running remote VM
   49       private final VirtualMachine vm;
   50   
   51       // Thread transferring remote error stream to our error stream
   52       private Thread errThread = null;
   53   
   54       // Thread transferring remote output stream to our output stream
   55       private Thread outThread = null;
   56   
   57       // Mode for tracing the Trace program (default= 0 off)
   58       private int debugTraceMode = 0;
   59   
   60       //  Do we want to watch assignments to fields
   61       private boolean watchFields = false;
   62   
   63       // Class patterns for which we don't want events
   64       private String[] excludes = {"java.*", "javax.*", "sun.*",
   65                                    "com.sun.*"};
   66   
   67       /**
   68        * main
   69        */
   70       public static void main(String[] args) {
   71           new Trace(args);
   72       }
   73   
   74       /**
   75        * Parse the command line arguments.
   76        * Launch target VM.
   77        * Generate the trace.
   78        */
   79       Trace(String[] args) {
   80           PrintWriter writer = new PrintWriter(System.out);
   81           int inx;
   82           for (inx = 0; inx < args.length; ++inx) {
   83               String arg = args[inx];
   84               if (arg.charAt(0) != '-') {
   85                   break;
   86               }
   87               if (arg.equals("-output")) {
   88                   try {
   89                       writer = new PrintWriter(new FileWriter(args[++inx]));
   90                   } catch (IOException exc) {
   91                       System.err.println("Cannot open output file: " + args[inx]
   92                                          + " - " +  exc);
   93                       System.exit(1);
   94                   }
   95               } else if (arg.equals("-all")) {
   96                   excludes = new String[0];
   97               } else if (arg.equals("-fields")) {
   98                   watchFields = true;
   99               } else if (arg.equals("-dbgtrace")) {
  100                   debugTraceMode = Integer.parseInt(args[++inx]);
  101               } else if (arg.equals("-help")) {
  102                   usage();
  103                   System.exit(0);
  104               } else {
  105                   System.err.println("No option: " + arg);
  106                   usage();
  107                   System.exit(1);
  108               }
  109           }
  110           if (inx >= args.length) {
  111               System.err.println("<class> missing");
  112               usage();
  113               System.exit(1);
  114           }
  115           StringBuffer sb = new StringBuffer();
  116           sb.append(args[inx]);
  117           for (++inx; inx < args.length; ++inx) {
  118               sb.append(' ');
  119               sb.append(args[inx]);
  120           }
  121           vm = launchTarget(sb.toString());
  122           generateTrace(writer);
  123       }
  124   
  125   
  126       /**
  127        * Generate the trace.
  128        * Enable events, start thread to display events,
  129        * start threads to forward remote error and output streams,
  130        * resume the remote VM, wait for the final event, and shutdown.
  131        */
  132       void generateTrace(PrintWriter writer) {
  133           vm.setDebugTraceMode(debugTraceMode);
  134           EventThread eventThread = new EventThread(vm, excludes, writer);
  135           eventThread.setEventRequests(watchFields);
  136           eventThread.start();
  137           redirectOutput();
  138           vm.resume();
  139   
  140           // Shutdown begins when event thread terminates
  141           try {
  142               eventThread.join();
  143               errThread.join(); // Make sure output is forwarded
  144               outThread.join(); // before we exit
  145           } catch (InterruptedException exc) {
  146               // we don't interrupt
  147           }
  148           writer.close();
  149       }
  150   
  151       /**
  152        * Launch target VM.
  153        * Forward target's output and error.
  154        */
  155       VirtualMachine launchTarget(String mainArgs) {
  156           LaunchingConnector connector = findLaunchingConnector();
  157           Map<String, Connector.Argument> arguments =
  158              connectorArguments(connector, mainArgs);
  159           try {
  160               return connector.launch(arguments);
  161           } catch (IOException exc) {
  162               throw new Error("Unable to launch target VM: " + exc);
  163           } catch (IllegalConnectorArgumentsException exc) {
  164               throw new Error("Internal error: " + exc);
  165           } catch (VMStartException exc) {
  166               throw new Error("Target VM failed to initialize: " +
  167                               exc.getMessage());
  168           }
  169       }
  170   
  171       void redirectOutput() {
  172           Process process = vm.process();
  173   
  174           // Copy target's output and error to our output and error.
  175           errThread = new StreamRedirectThread("error reader",
  176                                                process.getErrorStream(),
  177                                                System.err);
  178           outThread = new StreamRedirectThread("output reader",
  179                                                process.getInputStream(),
  180                                                System.out);
  181           errThread.start();
  182           outThread.start();
  183       }
  184   
  185       /**
  186        * Find a com.sun.jdi.CommandLineLaunch connector
  187        */
  188       LaunchingConnector findLaunchingConnector() {
  189           List<Connector> connectors = Bootstrap.virtualMachineManager().allConnectors();
  190           for (Connector connector : connectors) {
  191               if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {
  192                   return (LaunchingConnector)connector;
  193               }
  194           }
  195           throw new Error("No launching connector");
  196       }
  197   
  198       /**
  199        * Return the launching connector's arguments.
  200        */
  201       Map<String, Connector.Argument> connectorArguments(LaunchingConnector connector, String mainArgs) {
  202           Map<String, Connector.Argument> arguments = connector.defaultArguments();
  203           Connector.Argument mainArg =
  204                              (Connector.Argument)arguments.get("main");
  205           if (mainArg == null) {
  206               throw new Error("Bad launching connector");
  207           }
  208           mainArg.setValue(mainArgs);
  209   
  210           if (watchFields) {
  211               // We need a VM that supports watchpoints
  212               Connector.Argument optionArg =
  213                   (Connector.Argument)arguments.get("options");
  214               if (optionArg == null) {
  215                   throw new Error("Bad launching connector");
  216               }
  217               optionArg.setValue("-classic");
  218           }
  219           return arguments;
  220       }
  221   
  222       /**
  223        * Print command line usage help
  224        */
  225       void usage() {
  226           System.err.println("Usage: java Trace <options> <class> <args>");
  227           System.err.println("<options> are:");
  228           System.err.println(
  229   "  -output <filename>   Output trace to <filename>");
  230           System.err.println(
  231   "  -all                 Include system classes in output");
  232           System.err.println(
  233   "  -help                Print this help message");
  234           System.err.println("<class> is the program to trace");
  235           System.err.println("<args> are the arguments to <class>");
  236       }
  237   }

Save This Page
Home » openjdk-7 » com.sun.tools.example » trace » [javadoc | source]