KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > tools > example > trace > Trace


1 /*
2  * @(#)Trace.java 1.6 05/11/17
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 /*
8  * Copyright (c) 1997-2001 by Sun Microsystems, Inc. All Rights Reserved.
9  *
10  * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
11  * modify and redistribute this software in source and binary code form,
12  * provided that i) this copyright notice and license appear on all copies of
13  * the software; and ii) Licensee does not utilize the software in a manner
14  * which is disparaging to Sun.
15  *
16  * This software is provided "AS IS," without a warranty of any kind. ALL
17  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
18  * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
19  * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
20  * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
21  * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
22  * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
23  * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
24  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
25  * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGES.
27  *
28  * This software is not designed or intended for use in on-line control of
29  * aircraft, air traffic, aircraft navigation or aircraft communications; or in
30  * the design, construction, operation or maintenance of any nuclear
31  * facility. Licensee represents and warrants that it will not use or
32  * redistribute the Software for such purposes.
33  */

34 package com.sun.tools.example.trace;
35
36 import com.sun.jdi.VirtualMachine;
37 import com.sun.jdi.Bootstrap;
38 import com.sun.jdi.connect.*;
39
40 import java.util.Map JavaDoc;
41 import java.util.List JavaDoc;
42 import java.util.Iterator JavaDoc;
43
44 import java.io.PrintWriter JavaDoc;
45 import java.io.FileWriter JavaDoc;
46 import java.io.IOException JavaDoc;
47
48 /**
49  * This program traces the execution of another program.
50  * See "java Trace -help".
51  * It is a simple example of the use of the Java Debug Interface.
52  *
53  * @version @(#) Trace.java 1.6 05/11/17 00:25:20
54  * @author Robert Field
55  */

56 public class Trace {
57
58     // Running remote VM
59
private final VirtualMachine vm;
60
61     // Thread transferring remote error stream to our error stream
62
private Thread JavaDoc errThread = null;
63
64     // Thread transferring remote output stream to our output stream
65
private Thread JavaDoc outThread = null;
66
67     // Mode for tracing the Trace program (default= 0 off)
68
private int debugTraceMode = 0;
69
70     // Do we want to watch assignments to fields
71
private boolean watchFields = false;
72
73     // Class patterns for which we don't want events
74
private String JavaDoc[] excludes = {"java.*", "javax.*", "sun.*",
75                  "com.sun.*"};
76
77     /**
78      * main
79      */

80     public static void main(String JavaDoc[] args) {
81     new Trace(args);
82     }
83
84     /**
85      * Parse the command line arguments.
86      * Launch target VM.
87      * Generate the trace.
88      */

89     Trace(String JavaDoc[] args) {
90     PrintWriter JavaDoc writer = new PrintWriter JavaDoc(System.out);
91     int inx;
92     for (inx = 0; inx < args.length; ++inx) {
93         String JavaDoc arg = args[inx];
94         if (arg.charAt(0) != '-') {
95         break;
96         }
97         if (arg.equals("-output")) {
98         try {
99             writer = new PrintWriter JavaDoc(new FileWriter JavaDoc(args[++inx]));
100         } catch (IOException JavaDoc exc) {
101             System.err.println("Cannot open output file: " + args[inx]
102                        + " - " + exc);
103             System.exit(1);
104         }
105         } else if (arg.equals("-all")) {
106         excludes = new String JavaDoc[0];
107         } else if (arg.equals("-fields")) {
108         watchFields = true;
109         } else if (arg.equals("-dbgtrace")) {
110         debugTraceMode = Integer.parseInt(args[++inx]);
111         } else if (arg.equals("-help")) {
112         usage();
113         System.exit(0);
114         } else {
115         System.err.println("No option: " + arg);
116         usage();
117         System.exit(1);
118         }
119     }
120         if (inx >= args.length) {
121         System.err.println("<class> missing");
122             usage();
123             System.exit(1);
124         }
125         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
126         sb.append(args[inx]);
127         for (++inx; inx < args.length; ++inx) {
128             sb.append(' ');
129             sb.append(args[inx]);
130         }
131         vm = launchTarget(sb.toString());
132         generateTrace(writer);
133     }
134
135
136     /**
137      * Generate the trace.
138      * Enable events, start thread to display events,
139      * start threads to forward remote error and output streams,
140      * resume the remote VM, wait for the final event, and shutdown.
141      */

142     void generateTrace(PrintWriter JavaDoc writer) {
143         vm.setDebugTraceMode(debugTraceMode);
144         EventThread eventThread = new EventThread(vm, excludes, writer);
145         eventThread.setEventRequests(watchFields);
146         eventThread.start();
147         redirectOutput();
148         vm.resume();
149
150         // Shutdown begins when event thread terminates
151
try {
152         eventThread.join();
153         errThread.join(); // Make sure output is forwarded
154
outThread.join(); // before we exit
155
} catch (InterruptedException JavaDoc exc) {
156         // we don't interrupt
157
}
158     writer.close();
159     }
160
161     /**
162      * Launch target VM.
163      * Forward target's output and error.
164      */

165     VirtualMachine launchTarget(String JavaDoc mainArgs) {
166     LaunchingConnector connector = findLaunchingConnector();
167     Map JavaDoc arguments = connectorArguments(connector, mainArgs);
168         try {
169         return connector.launch(arguments);
170         } catch (IOException JavaDoc exc) {
171             throw new Error JavaDoc("Unable to launch target VM: " + exc);
172         } catch (IllegalConnectorArgumentsException exc) {
173             throw new Error JavaDoc("Internal error: " + exc);
174         } catch (VMStartException exc) {
175             throw new Error JavaDoc("Target VM failed to initialize: " +
176                 exc.getMessage());
177         }
178     }
179
180     void redirectOutput() {
181         Process JavaDoc process = vm.process();
182
183         // Copy target's output and error to our output and error.
184
errThread = new StreamRedirectThread("error reader",
185                                              process.getErrorStream(),
186                                              System.err);
187         outThread = new StreamRedirectThread("output reader",
188                                              process.getInputStream(),
189                                              System.out);
190         errThread.start();
191         outThread.start();
192     }
193
194     /**
195      * Find a com.sun.jdi.CommandLineLaunch connector
196      */

197     LaunchingConnector findLaunchingConnector() {
198         List JavaDoc connectors = Bootstrap.virtualMachineManager().allConnectors();
199         Iterator JavaDoc iter = connectors.iterator();
200         while (iter.hasNext()) {
201             Connector connector = (Connector)iter.next();
202             if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {
203                 return (LaunchingConnector)connector;
204             }
205         }
206         throw new Error JavaDoc("No launching connector");
207     }
208
209     /**
210      * Return the launching connector's arguments.
211      */

212     Map JavaDoc connectorArguments(LaunchingConnector connector, String JavaDoc mainArgs) {
213         Map JavaDoc arguments = connector.defaultArguments();
214         Connector.Argument mainArg =
215                        (Connector.Argument)arguments.get("main");
216         if (mainArg == null) {
217             throw new Error JavaDoc("Bad launching connector");
218         }
219     mainArg.setValue(mainArgs);
220
221     if (watchFields) {
222         // We need a VM that supports watchpoints
223
Connector.Argument optionArg =
224         (Connector.Argument)arguments.get("options");
225         if (optionArg == null) {
226         throw new Error JavaDoc("Bad launching connector");
227         }
228         optionArg.setValue("-classic");
229     }
230     return arguments;
231     }
232
233     /**
234      * Print command line usage help
235      */

236     void usage() {
237     System.err.println("Usage: java Trace <options> <class> <args>");
238     System.err.println("<options> are:");
239     System.err.println(
240 " -output <filename> Output trace to <filename>");
241     System.err.println(
242 " -all Include system classes in output");
243     System.err.println(
244 " -help Print this help message");
245     System.err.println("<class> is the program to trace");
246     System.err.println("<args> are the arguments to <class>");
247     }
248 }
249
Popular Tags