Mercurial > hg > graal-compiler
annotate agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java @ 12932:7fe6ef09d242
8025638: jmap returns 0 instead of 1 when it fails.
Summary: Re-factored some code handling return values and fails/errors during tool execution.
Reviewed-by: sla, kevinw
Contributed-by: fredrik.arvidsson@oracle.com
author | farvidsson |
---|---|
date | Wed, 16 Oct 2013 09:20:23 +0200 |
parents | 38ea2efa32a7 |
children |
rev | line source |
---|---|
0 | 1 /* |
8750 | 2 * Copyright (c) 2003, 2013, 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:
218
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
218
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:
218
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 package sun.jvm.hotspot.tools; | |
26 | |
27 import java.io.*; | |
28 import java.util.*; | |
29 import sun.jvm.hotspot.code.*; | |
30 import sun.jvm.hotspot.interpreter.*; | |
31 import sun.jvm.hotspot.debugger.*; | |
32 import sun.jvm.hotspot.debugger.cdbg.*; | |
33 import sun.jvm.hotspot.oops.*; | |
34 import sun.jvm.hotspot.runtime.*; | |
8750 | 35 import sun.jvm.hotspot.utilities.PlatformInfo; |
0 | 36 |
37 public class PStack extends Tool { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6163
diff
changeset
|
38 // in non-verbose mode, Method*s are not printed in java frames |
0 | 39 public PStack(boolean v, boolean concurrentLocks) { |
40 this.verbose = v; | |
41 this.concurrentLocks = concurrentLocks; | |
42 } | |
43 | |
44 public PStack() { | |
45 this(true, true); | |
46 } | |
47 | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
8750
diff
changeset
|
48 public PStack(JVMDebugger d) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
8750
diff
changeset
|
49 super(d); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
8750
diff
changeset
|
50 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
8750
diff
changeset
|
51 |
0 | 52 public void run() { |
53 run(System.out); | |
54 } | |
55 | |
56 public void run(PrintStream out) { | |
57 Debugger dbg = getAgent().getDebugger(); | |
8103 | 58 run(out, dbg); |
0 | 59 } |
60 | |
61 public void run(PrintStream out, Debugger dbg) { | |
8750 | 62 if (PlatformInfo.getOS().equals("darwin")) { |
63 out.println("Not available on Darwin"); | |
64 return; | |
65 } | |
66 | |
0 | 67 CDebugger cdbg = dbg.getCDebugger(); |
68 if (cdbg != null) { | |
69 ConcurrentLocksPrinter concLocksPrinter = null; | |
8103 | 70 // compute and cache java Vframes. |
71 initJFrameCache(); | |
72 if (concurrentLocks) { | |
73 concLocksPrinter = new ConcurrentLocksPrinter(); | |
74 } | |
75 // print Java level deadlocks | |
76 try { | |
77 DeadlockDetector.print(out); | |
78 } catch (Exception exp) { | |
79 out.println("can't print deadlock information: " + exp.getMessage()); | |
0 | 80 } |
81 | |
82 List l = cdbg.getThreadList(); | |
83 final boolean cdbgCanDemangle = cdbg.canDemangle(); | |
84 for (Iterator itr = l.iterator() ; itr.hasNext();) { | |
85 ThreadProxy th = (ThreadProxy) itr.next(); | |
86 try { | |
87 CFrame f = cdbg.topFrameForThread(th); | |
88 out.print("----------------- "); | |
89 out.print(th); | |
90 out.println(" -----------------"); | |
91 while (f != null) { | |
92 ClosestSymbol sym = f.closestSymbolToPC(); | |
93 Address pc = f.pc(); | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
94 out.print(pc + "\t"); |
0 | 95 if (sym != null) { |
96 String name = sym.getName(); | |
97 if (cdbgCanDemangle) { | |
98 name = cdbg.demangle(name); | |
99 } | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
100 out.print(name); |
0 | 101 long diff = sym.getOffset(); |
102 if (diff != 0L) { | |
103 out.print(" + 0x" + Long.toHexString(diff)); | |
104 } | |
105 out.println(); | |
106 } else { | |
8103 | 107 // look for one or more java frames |
108 String[] names = null; | |
109 // check interpreter frame | |
110 Interpreter interp = VM.getVM().getInterpreter(); | |
111 if (interp.contains(pc)) { | |
112 names = getJavaNames(th, f.localVariableBase()); | |
113 // print codelet name if we can't determine method | |
114 if (names == null || names.length == 0) { | |
115 out.print("<interpreter> "); | |
116 InterpreterCodelet ic = interp.getCodeletContaining(pc); | |
117 if (ic != null) { | |
118 String desc = ic.getDescription(); | |
119 if (desc != null) out.print(desc); | |
120 } | |
121 out.println(); | |
122 } | |
123 } else { | |
124 // look for known code blobs | |
125 CodeCache c = VM.getVM().getCodeCache(); | |
126 if (c.contains(pc)) { | |
127 CodeBlob cb = c.findBlobUnsafe(pc); | |
128 if (cb.isNMethod()) { | |
129 names = getJavaNames(th, f.localVariableBase()); | |
130 // just print compiled code, if can't determine method | |
131 if (names == null || names.length == 0) { | |
132 out.println("<Unknown compiled code>"); | |
133 } | |
134 } else if (cb.isBufferBlob()) { | |
135 out.println("<StubRoutines>"); | |
136 } else if (cb.isRuntimeStub()) { | |
137 out.println("<RuntimeStub>"); | |
138 } else if (cb.isDeoptimizationStub()) { | |
139 out.println("<DeoptimizationStub>"); | |
140 } else if (cb.isUncommonTrapStub()) { | |
141 out.println("<UncommonTrap>"); | |
142 } else if (cb.isExceptionStub()) { | |
143 out.println("<ExceptionStub>"); | |
144 } else if (cb.isSafepointStub()) { | |
145 out.println("<SafepointStub>"); | |
146 } else { | |
147 out.println("<Unknown code blob>"); | |
148 } | |
149 } else { | |
150 printUnknown(out); | |
151 } | |
152 } | |
153 // print java frames, if any | |
154 if (names != null && names.length != 0) { | |
155 // print java frame(s) | |
156 for (int i = 0; i < names.length; i++) { | |
157 out.println(names[i]); | |
158 } | |
159 } | |
0 | 160 } |
6163 | 161 f = f.sender(th); |
0 | 162 } |
163 } catch (Exception exp) { | |
164 exp.printStackTrace(); | |
165 // continue, may be we can do a better job for other threads | |
166 } | |
8103 | 167 if (concurrentLocks) { |
0 | 168 JavaThread jthread = (JavaThread) proxyToThread.get(th); |
169 if (jthread != null) { | |
170 concLocksPrinter.print(jthread, out); | |
171 } | |
172 } | |
173 } // for threads | |
174 } else { | |
175 if (getDebugeeType() == DEBUGEE_REMOTE) { | |
176 out.println("remote configuration is not yet implemented"); | |
177 } else { | |
178 out.println("not yet implemented (debugger does not support CDebugger)!"); | |
179 } | |
180 } | |
181 } | |
182 | |
183 public static void main(String[] args) throws Exception { | |
184 PStack t = new PStack(); | |
12932
7fe6ef09d242
8025638: jmap returns 0 instead of 1 when it fails.
farvidsson
parents:
11054
diff
changeset
|
185 t.execute(args); |
0 | 186 } |
187 | |
188 // -- Internals only below this point | |
189 private Map jframeCache; // Map<ThreadProxy, JavaVFrame[]> | |
190 private Map proxyToThread; // Map<ThreadProxy, JavaThread> | |
191 private PrintStream out; | |
192 private boolean verbose; | |
193 private boolean concurrentLocks; | |
194 | |
195 private void initJFrameCache() { | |
196 // cache frames for subsequent reference | |
197 jframeCache = new HashMap(); | |
198 proxyToThread = new HashMap(); | |
199 Threads threads = VM.getVM().getThreads(); | |
200 for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) { | |
201 List tmp = new ArrayList(10); | |
202 try { | |
203 for (JavaVFrame vf = cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) { | |
204 tmp.add(vf); | |
205 } | |
206 } catch (Exception exp) { | |
207 // may be we may get frames for other threads, continue | |
208 // after printing stack trace. | |
209 exp.printStackTrace(); | |
210 } | |
211 JavaVFrame[] jvframes = new JavaVFrame[tmp.size()]; | |
212 System.arraycopy(tmp.toArray(), 0, jvframes, 0, jvframes.length); | |
213 jframeCache.put(cur.getThreadProxy(), jvframes); | |
214 proxyToThread.put(cur.getThreadProxy(), cur); | |
215 } | |
216 } | |
217 | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
218 private void printUnknown(PrintStream out) { |
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
219 out.println("\t????????"); |
0 | 220 } |
221 | |
222 private String[] getJavaNames(ThreadProxy th, Address fp) { | |
223 if (fp == null) { | |
224 return null; | |
225 } | |
226 JavaVFrame[] jvframes = (JavaVFrame[]) jframeCache.get(th); | |
227 if (jvframes == null) return null; // not a java thread | |
228 List names = new ArrayList(10); | |
229 for (int fCount = 0; fCount < jvframes.length; fCount++) { | |
230 JavaVFrame vf = jvframes[fCount]; | |
231 Frame f = vf.getFrame(); | |
232 if (fp.equals(f.getFP())) { | |
233 StringBuffer sb = new StringBuffer(); | |
234 Method method = vf.getMethod(); | |
235 // a special char to identify java frames in output | |
236 sb.append("* "); | |
237 sb.append(method.externalNameAndSignature()); | |
238 sb.append(" bci:" + vf.getBCI()); | |
239 int lineNumber = method.getLineNumberFromBCI(vf.getBCI()); | |
240 if (lineNumber != -1) { | |
241 sb.append(" line:" + lineNumber); | |
242 } | |
243 | |
244 if (verbose) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6163
diff
changeset
|
245 sb.append(" Method*:" + method.getAddress()); |
0 | 246 } |
247 | |
248 if (vf.isCompiledFrame()) { | |
249 sb.append(" (Compiled frame"); | |
250 if (vf.isDeoptimized()) { | |
251 sb.append(" [deoptimized]"); | |
252 } | |
253 } else if (vf.isInterpretedFrame()) { | |
254 sb.append(" (Interpreted frame"); | |
255 } | |
256 if (vf.mayBeImpreciseDbg()) { | |
257 sb.append("; information may be imprecise"); | |
258 } | |
259 sb.append(")"); | |
260 names.add(sb.toString()); | |
261 } | |
262 } | |
263 String[] res = new String[names.size()]; | |
264 System.arraycopy(names.toArray(), 0, res, 0, res.length); | |
265 return res; | |
266 } | |
267 } |