annotate agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 package sun.jvm.hotspot;
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 import sun.jvm.hotspot.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
28 import sun.jvm.hotspot.debugger.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30 import java.io.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
31 import java.util.*;
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33 public class CLHSDB {
a61af66fc99e Initial load
duke
parents:
diff changeset
34 public static void main(String[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
35 new CLHSDB(args).run();
a61af66fc99e Initial load
duke
parents:
diff changeset
36 }
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 private void run() {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // At this point, if pidText != null we are supposed to attach to it.
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // Else, if execPath != null, it is the path of a jdk/bin/java
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // and coreFilename is the pathname of a core file we are
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // supposed to attach to.
a61af66fc99e Initial load
duke
parents:
diff changeset
43
a61af66fc99e Initial load
duke
parents:
diff changeset
44 agent = new HotSpotAgent();
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 Runtime.getRuntime().addShutdownHook(new java.lang.Thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
47 public void run() {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 detachDebugger();
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50 });
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 if (pidText != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 attachDebugger(pidText);
a61af66fc99e Initial load
duke
parents:
diff changeset
54 } else if (execPath != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
55 attachDebugger(execPath, coreFilename);
a61af66fc99e Initial load
duke
parents:
diff changeset
56 }
a61af66fc99e Initial load
duke
parents:
diff changeset
57
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 CommandProcessor.DebuggerInterface di = new CommandProcessor.DebuggerInterface() {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 public HotSpotAgent getAgent() {
a61af66fc99e Initial load
duke
parents:
diff changeset
61 return agent;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 }
a61af66fc99e Initial load
duke
parents:
diff changeset
63 public boolean isAttached() {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 return attached;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66 public void attach(String pid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
67 attachDebugger(pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
68 }
a61af66fc99e Initial load
duke
parents:
diff changeset
69 public void attach(String java, String core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
70 attachDebugger(java, core);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72 public void detach() {
a61af66fc99e Initial load
duke
parents:
diff changeset
73 detachDebugger();
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 public void reattach() {
a61af66fc99e Initial load
duke
parents:
diff changeset
76 if (attached) {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 detachDebugger();
a61af66fc99e Initial load
duke
parents:
diff changeset
78 }
a61af66fc99e Initial load
duke
parents:
diff changeset
79 if (pidText != null) {
a61af66fc99e Initial load
duke
parents:
diff changeset
80 attach(pidText);
a61af66fc99e Initial load
duke
parents:
diff changeset
81 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 attach(execPath, coreFilename);
a61af66fc99e Initial load
duke
parents:
diff changeset
83 }
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85 };
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 BufferedReader in =
a61af66fc99e Initial load
duke
parents:
diff changeset
89 new BufferedReader(new InputStreamReader(System.in));
a61af66fc99e Initial load
duke
parents:
diff changeset
90 CommandProcessor cp = new CommandProcessor(di, in, System.out, System.err);
a61af66fc99e Initial load
duke
parents:
diff changeset
91 cp.run(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 //--------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // Internals only below this point
a61af66fc99e Initial load
duke
parents:
diff changeset
97 //
a61af66fc99e Initial load
duke
parents:
diff changeset
98 private HotSpotAgent agent;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 private boolean attached;
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // These had to be made data members because they are referenced in inner classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
101 private String pidText;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 private int pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 private String execPath;
a61af66fc99e Initial load
duke
parents:
diff changeset
104 private String coreFilename;
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 private void doUsage() {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 System.out.println("Usage: java CLHSDB [[pid] | [path-to-java-executable [path-to-corefile]] | help ]");
a61af66fc99e Initial load
duke
parents:
diff changeset
108 System.out.println(" pid: attach to the process whose id is 'pid'");
a61af66fc99e Initial load
duke
parents:
diff changeset
109 System.out.println(" path-to-java-executable: Debug a core file produced by this program");
a61af66fc99e Initial load
duke
parents:
diff changeset
110 System.out.println(" path-to-corefile: Debug this corefile. The default is 'core'");
a61af66fc99e Initial load
duke
parents:
diff changeset
111 System.out.println(" If no arguments are specified, you can select what to do from the GUI.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
112 HotSpotAgent.showUsage();
a61af66fc99e Initial load
duke
parents:
diff changeset
113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 private CLHSDB(String[] args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 switch (args.length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
117 case (0):
a61af66fc99e Initial load
duke
parents:
diff changeset
118 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
119
a61af66fc99e Initial load
duke
parents:
diff changeset
120 case (1):
a61af66fc99e Initial load
duke
parents:
diff changeset
121 if (args[0].equals("help") || args[0].equals("-help")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
122 doUsage();
a61af66fc99e Initial load
duke
parents:
diff changeset
123 System.exit(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125 // If all numbers, it is a PID to attach to
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // Else, it is a pathname to a .../bin/java for a core file.
a61af66fc99e Initial load
duke
parents:
diff changeset
127 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
128 int unused = Integer.parseInt(args[0]);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // If we get here, we have a PID and not a core file name
a61af66fc99e Initial load
duke
parents:
diff changeset
130 pidText = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
131 } catch (NumberFormatException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 execPath = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
133 coreFilename = "core";
a61af66fc99e Initial load
duke
parents:
diff changeset
134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
135 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 case (2):
a61af66fc99e Initial load
duke
parents:
diff changeset
138 execPath = args[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
139 coreFilename = args[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
140 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
143 System.out.println("HSDB Error: Too many options specified");
a61af66fc99e Initial load
duke
parents:
diff changeset
144 doUsage();
a61af66fc99e Initial load
duke
parents:
diff changeset
145 System.exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 /** NOTE we are in a different thread here than either the main
a61af66fc99e Initial load
duke
parents:
diff changeset
150 thread or the Swing/AWT event handler thread, so we must be very
a61af66fc99e Initial load
duke
parents:
diff changeset
151 careful when creating or removing widgets */
a61af66fc99e Initial load
duke
parents:
diff changeset
152 private void attachDebugger(String pidText) {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 this.pidText = pidText;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 pid = Integer.parseInt(pidText);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157 catch (NumberFormatException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 System.err.print("Unable to parse process ID \"" + pidText + "\".\nPlease enter a number.");
a61af66fc99e Initial load
duke
parents:
diff changeset
159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 System.err.println("Attaching to process " + pid + ", please wait...");
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // FIXME: display exec'd debugger's output messages during this
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // lengthy call
a61af66fc99e Initial load
duke
parents:
diff changeset
166 agent.attach(pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 attached = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169 catch (DebuggerException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
170 final String errMsg = formatMessage(e.getMessage(), 80);
a61af66fc99e Initial load
duke
parents:
diff changeset
171 System.err.println("Unable to connect to process ID " + pid + ":\n\n" + errMsg);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 agent.detach();
a61af66fc99e Initial load
duke
parents:
diff changeset
173 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 /** NOTE we are in a different thread here than either the main
a61af66fc99e Initial load
duke
parents:
diff changeset
178 thread or the Swing/AWT event handler thread, so we must be very
a61af66fc99e Initial load
duke
parents:
diff changeset
179 careful when creating or removing widgets */
a61af66fc99e Initial load
duke
parents:
diff changeset
180 private void attachDebugger(final String executablePath, final String corePath) {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Try to open this core file
a61af66fc99e Initial load
duke
parents:
diff changeset
182 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 System.err.println("Opening core file, please wait...");
a61af66fc99e Initial load
duke
parents:
diff changeset
184
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // FIXME: display exec'd debugger's output messages during this
a61af66fc99e Initial load
duke
parents:
diff changeset
186 // lengthy call
a61af66fc99e Initial load
duke
parents:
diff changeset
187 agent.attach(executablePath, corePath);
a61af66fc99e Initial load
duke
parents:
diff changeset
188 attached = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190 catch (DebuggerException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 final String errMsg = formatMessage(e.getMessage(), 80);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 System.err.println("Unable to open core file\n" + corePath + ":\n\n" + errMsg);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 agent.detach();
a61af66fc99e Initial load
duke
parents:
diff changeset
194 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
195 }
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 /** NOTE we are in a different thread here than either the main
a61af66fc99e Initial load
duke
parents:
diff changeset
199 thread or the Swing/AWT event handler thread, so we must be very
a61af66fc99e Initial load
duke
parents:
diff changeset
200 careful when creating or removing widgets */
a61af66fc99e Initial load
duke
parents:
diff changeset
201 private void connect(final String remoteMachineName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 // Try to open this core file
a61af66fc99e Initial load
duke
parents:
diff changeset
203 try {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 System.err.println("Connecting to debug server, please wait...");
a61af66fc99e Initial load
duke
parents:
diff changeset
205 agent.attach(remoteMachineName);
a61af66fc99e Initial load
duke
parents:
diff changeset
206 attached = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208 catch (DebuggerException e) {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 final String errMsg = formatMessage(e.getMessage(), 80);
a61af66fc99e Initial load
duke
parents:
diff changeset
210 System.err.println("Unable to connect to machine \"" + remoteMachineName + "\":\n\n" + errMsg);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 agent.detach();
a61af66fc99e Initial load
duke
parents:
diff changeset
212 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 private void detachDebugger() {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (!attached) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220 agent.detach();
a61af66fc99e Initial load
duke
parents:
diff changeset
221 attached = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 private void detach() {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 detachDebugger();
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 /** Punctuates the given string with \n's where necessary to not
a61af66fc99e Initial load
duke
parents:
diff changeset
229 exceed the given number of characters per line. Strips
a61af66fc99e Initial load
duke
parents:
diff changeset
230 extraneous whitespace. */
a61af66fc99e Initial load
duke
parents:
diff changeset
231 private String formatMessage(String message, int charsPerLine) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 StringBuffer buf = new StringBuffer(message.length());
a61af66fc99e Initial load
duke
parents:
diff changeset
233 StringTokenizer tokenizer = new StringTokenizer(message);
a61af66fc99e Initial load
duke
parents:
diff changeset
234 int curLineLength = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
235 while (tokenizer.hasMoreTokens()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 String tok = tokenizer.nextToken();
a61af66fc99e Initial load
duke
parents:
diff changeset
237 if (curLineLength + tok.length() > charsPerLine) {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 buf.append('\n');
a61af66fc99e Initial load
duke
parents:
diff changeset
239 curLineLength = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
240 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
241 if (curLineLength != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 buf.append(' ');
a61af66fc99e Initial load
duke
parents:
diff changeset
243 ++curLineLength;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246 buf.append(tok);
a61af66fc99e Initial load
duke
parents:
diff changeset
247 curLineLength += tok.length();
a61af66fc99e Initial load
duke
parents:
diff changeset
248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
249 return buf.toString();
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }