Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java @ 11060:068b406e307f
7060111: race condition in VMError::report_and_die()
Reviewed-by: zgu, coleenp
Contributed-by: volker.simonis@gmail.com
author | fparain |
---|---|
date | Mon, 01 Jul 2013 09:13:19 +0000 |
parents | 38ea2efa32a7 |
children | de6a9e811145 |
rev | line source |
---|---|
0 | 1 /* |
3939 | 2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot; | |
26 | |
27 import sun.jvm.hotspot.*; | |
28 import sun.jvm.hotspot.debugger.*; | |
29 | |
30 import java.io.*; | |
31 import java.util.*; | |
32 | |
33 public class CLHSDB { | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
34 |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
35 public CLHSDB(JVMDebugger d) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
36 jvmDebugger = d; |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
37 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
38 |
0 | 39 public static void main(String[] args) { |
40 new CLHSDB(args).run(); | |
41 } | |
42 | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
43 public void run() { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
44 // If jvmDebugger is already set, we have been given a JVMDebugger. |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
45 // Otherwise, if pidText != null we are supposed to attach to it. |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
46 // Finally, if execPath != null, it is the path of a jdk/bin/java |
0 | 47 // and coreFilename is the pathname of a core file we are |
48 // supposed to attach to. | |
49 | |
50 agent = new HotSpotAgent(); | |
51 | |
52 Runtime.getRuntime().addShutdownHook(new java.lang.Thread() { | |
53 public void run() { | |
54 detachDebugger(); | |
55 } | |
56 }); | |
57 | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
58 if (jvmDebugger != null) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
59 attachDebugger(jvmDebugger); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
60 } else if (pidText != null) { |
0 | 61 attachDebugger(pidText); |
62 } else if (execPath != null) { | |
63 attachDebugger(execPath, coreFilename); | |
64 } | |
65 | |
66 | |
67 CommandProcessor.DebuggerInterface di = new CommandProcessor.DebuggerInterface() { | |
68 public HotSpotAgent getAgent() { | |
69 return agent; | |
70 } | |
71 public boolean isAttached() { | |
72 return attached; | |
73 } | |
74 public void attach(String pid) { | |
75 attachDebugger(pid); | |
76 } | |
77 public void attach(String java, String core) { | |
78 attachDebugger(java, core); | |
79 } | |
80 public void detach() { | |
81 detachDebugger(); | |
82 } | |
83 public void reattach() { | |
84 if (attached) { | |
85 detachDebugger(); | |
86 } | |
87 if (pidText != null) { | |
88 attach(pidText); | |
89 } else { | |
90 attach(execPath, coreFilename); | |
91 } | |
92 } | |
93 }; | |
94 | |
95 | |
96 BufferedReader in = | |
97 new BufferedReader(new InputStreamReader(System.in)); | |
98 CommandProcessor cp = new CommandProcessor(di, in, System.out, System.err); | |
99 cp.run(true); | |
100 | |
101 } | |
102 | |
103 //-------------------------------------------------------------------------------- | |
104 // Internals only below this point | |
105 // | |
106 private HotSpotAgent agent; | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
107 private JVMDebugger jvmDebugger; |
0 | 108 private boolean attached; |
109 // These had to be made data members because they are referenced in inner classes. | |
110 private String pidText; | |
111 private int pid; | |
112 private String execPath; | |
113 private String coreFilename; | |
114 | |
115 private void doUsage() { | |
116 System.out.println("Usage: java CLHSDB [[pid] | [path-to-java-executable [path-to-corefile]] | help ]"); | |
117 System.out.println(" pid: attach to the process whose id is 'pid'"); | |
118 System.out.println(" path-to-java-executable: Debug a core file produced by this program"); | |
119 System.out.println(" path-to-corefile: Debug this corefile. The default is 'core'"); | |
120 System.out.println(" If no arguments are specified, you can select what to do from the GUI.\n"); | |
121 HotSpotAgent.showUsage(); | |
122 } | |
123 | |
124 private CLHSDB(String[] args) { | |
125 switch (args.length) { | |
126 case (0): | |
127 break; | |
128 | |
129 case (1): | |
130 if (args[0].equals("help") || args[0].equals("-help")) { | |
131 doUsage(); | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
132 return; |
0 | 133 } |
134 // If all numbers, it is a PID to attach to | |
135 // Else, it is a pathname to a .../bin/java for a core file. | |
136 try { | |
137 int unused = Integer.parseInt(args[0]); | |
138 // If we get here, we have a PID and not a core file name | |
139 pidText = args[0]; | |
140 } catch (NumberFormatException e) { | |
141 execPath = args[0]; | |
142 coreFilename = "core"; | |
143 } | |
144 break; | |
145 | |
146 case (2): | |
147 execPath = args[0]; | |
148 coreFilename = args[1]; | |
149 break; | |
150 | |
151 default: | |
152 System.out.println("HSDB Error: Too many options specified"); | |
153 doUsage(); | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
154 return; |
0 | 155 } |
156 } | |
157 | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
158 private void attachDebugger(JVMDebugger d) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
159 agent.attach(d); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
160 attached = true; |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
161 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
3939
diff
changeset
|
162 |
0 | 163 /** NOTE we are in a different thread here than either the main |
164 thread or the Swing/AWT event handler thread, so we must be very | |
165 careful when creating or removing widgets */ | |
166 private void attachDebugger(String pidText) { | |
167 try { | |
168 this.pidText = pidText; | |
169 pid = Integer.parseInt(pidText); | |
170 } | |
171 catch (NumberFormatException e) { | |
172 System.err.print("Unable to parse process ID \"" + pidText + "\".\nPlease enter a number."); | |
173 } | |
174 | |
175 try { | |
176 System.err.println("Attaching to process " + pid + ", please wait..."); | |
177 | |
178 // FIXME: display exec'd debugger's output messages during this | |
179 // lengthy call | |
180 agent.attach(pid); | |
181 attached = true; | |
182 } | |
183 catch (DebuggerException e) { | |
184 final String errMsg = formatMessage(e.getMessage(), 80); | |
185 System.err.println("Unable to connect to process ID " + pid + ":\n\n" + errMsg); | |
186 agent.detach(); | |
3939 | 187 e.printStackTrace(); |
0 | 188 return; |
189 } | |
190 } | |
191 | |
192 /** NOTE we are in a different thread here than either the main | |
193 thread or the Swing/AWT event handler thread, so we must be very | |
194 careful when creating or removing widgets */ | |
195 private void attachDebugger(final String executablePath, final String corePath) { | |
196 // Try to open this core file | |
197 try { | |
198 System.err.println("Opening core file, please wait..."); | |
199 | |
200 // FIXME: display exec'd debugger's output messages during this | |
201 // lengthy call | |
202 agent.attach(executablePath, corePath); | |
203 attached = true; | |
204 } | |
205 catch (DebuggerException e) { | |
206 final String errMsg = formatMessage(e.getMessage(), 80); | |
207 System.err.println("Unable to open core file\n" + corePath + ":\n\n" + errMsg); | |
208 agent.detach(); | |
3939 | 209 e.printStackTrace(); |
0 | 210 return; |
211 } | |
212 } | |
213 | |
214 /** NOTE we are in a different thread here than either the main | |
215 thread or the Swing/AWT event handler thread, so we must be very | |
216 careful when creating or removing widgets */ | |
217 private void connect(final String remoteMachineName) { | |
218 // Try to open this core file | |
219 try { | |
220 System.err.println("Connecting to debug server, please wait..."); | |
221 agent.attach(remoteMachineName); | |
222 attached = true; | |
223 } | |
224 catch (DebuggerException e) { | |
225 final String errMsg = formatMessage(e.getMessage(), 80); | |
226 System.err.println("Unable to connect to machine \"" + remoteMachineName + "\":\n\n" + errMsg); | |
227 agent.detach(); | |
3939 | 228 e.printStackTrace(); |
0 | 229 return; |
230 } | |
231 } | |
232 | |
233 private void detachDebugger() { | |
234 if (!attached) { | |
235 return; | |
236 } | |
237 agent.detach(); | |
238 attached = false; | |
239 } | |
240 | |
241 private void detach() { | |
242 detachDebugger(); | |
243 } | |
244 | |
245 /** Punctuates the given string with \n's where necessary to not | |
246 exceed the given number of characters per line. Strips | |
247 extraneous whitespace. */ | |
248 private String formatMessage(String message, int charsPerLine) { | |
249 StringBuffer buf = new StringBuffer(message.length()); | |
250 StringTokenizer tokenizer = new StringTokenizer(message); | |
251 int curLineLength = 0; | |
252 while (tokenizer.hasMoreTokens()) { | |
253 String tok = tokenizer.nextToken(); | |
254 if (curLineLength + tok.length() > charsPerLine) { | |
255 buf.append('\n'); | |
256 curLineLength = 0; | |
257 } else { | |
258 if (curLineLength != 0) { | |
259 buf.append(' '); | |
260 ++curLineLength; | |
261 } | |
262 } | |
263 buf.append(tok); | |
264 curLineLength += tok.length(); | |
265 } | |
266 return buf.toString(); | |
267 } | |
268 } |