Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java @ 8750:39432a1cefdd
8003348: SA can not read core file on OS
Summary: Macosx uses Mach-O file format for binary files, not ELF format. Currently SA works on core files on other platforms, t his change enables SA work on core file generated on Darwin.
Reviewed-by: sla, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Thu, 14 Mar 2013 00:33:08 -0700 |
parents | 5ed317b25e23 |
children | 38ea2efa32a7 |
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 | |
48 public void run() { | |
49 run(System.out); | |
50 } | |
51 | |
52 public void run(PrintStream out) { | |
53 Debugger dbg = getAgent().getDebugger(); | |
8103 | 54 run(out, dbg); |
0 | 55 } |
56 | |
57 public void run(PrintStream out, Debugger dbg) { | |
8750 | 58 if (PlatformInfo.getOS().equals("darwin")) { |
59 out.println("Not available on Darwin"); | |
60 return; | |
61 } | |
62 | |
0 | 63 CDebugger cdbg = dbg.getCDebugger(); |
64 if (cdbg != null) { | |
65 ConcurrentLocksPrinter concLocksPrinter = null; | |
8103 | 66 // compute and cache java Vframes. |
67 initJFrameCache(); | |
68 if (concurrentLocks) { | |
69 concLocksPrinter = new ConcurrentLocksPrinter(); | |
70 } | |
71 // print Java level deadlocks | |
72 try { | |
73 DeadlockDetector.print(out); | |
74 } catch (Exception exp) { | |
75 out.println("can't print deadlock information: " + exp.getMessage()); | |
0 | 76 } |
77 | |
78 List l = cdbg.getThreadList(); | |
79 final boolean cdbgCanDemangle = cdbg.canDemangle(); | |
80 for (Iterator itr = l.iterator() ; itr.hasNext();) { | |
81 ThreadProxy th = (ThreadProxy) itr.next(); | |
82 try { | |
83 CFrame f = cdbg.topFrameForThread(th); | |
84 out.print("----------------- "); | |
85 out.print(th); | |
86 out.println(" -----------------"); | |
87 while (f != null) { | |
88 ClosestSymbol sym = f.closestSymbolToPC(); | |
89 Address pc = f.pc(); | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
90 out.print(pc + "\t"); |
0 | 91 if (sym != null) { |
92 String name = sym.getName(); | |
93 if (cdbgCanDemangle) { | |
94 name = cdbg.demangle(name); | |
95 } | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
96 out.print(name); |
0 | 97 long diff = sym.getOffset(); |
98 if (diff != 0L) { | |
99 out.print(" + 0x" + Long.toHexString(diff)); | |
100 } | |
101 out.println(); | |
102 } else { | |
8103 | 103 // look for one or more java frames |
104 String[] names = null; | |
105 // check interpreter frame | |
106 Interpreter interp = VM.getVM().getInterpreter(); | |
107 if (interp.contains(pc)) { | |
108 names = getJavaNames(th, f.localVariableBase()); | |
109 // print codelet name if we can't determine method | |
110 if (names == null || names.length == 0) { | |
111 out.print("<interpreter> "); | |
112 InterpreterCodelet ic = interp.getCodeletContaining(pc); | |
113 if (ic != null) { | |
114 String desc = ic.getDescription(); | |
115 if (desc != null) out.print(desc); | |
116 } | |
117 out.println(); | |
118 } | |
119 } else { | |
120 // look for known code blobs | |
121 CodeCache c = VM.getVM().getCodeCache(); | |
122 if (c.contains(pc)) { | |
123 CodeBlob cb = c.findBlobUnsafe(pc); | |
124 if (cb.isNMethod()) { | |
125 names = getJavaNames(th, f.localVariableBase()); | |
126 // just print compiled code, if can't determine method | |
127 if (names == null || names.length == 0) { | |
128 out.println("<Unknown compiled code>"); | |
129 } | |
130 } else if (cb.isBufferBlob()) { | |
131 out.println("<StubRoutines>"); | |
132 } else if (cb.isRuntimeStub()) { | |
133 out.println("<RuntimeStub>"); | |
134 } else if (cb.isDeoptimizationStub()) { | |
135 out.println("<DeoptimizationStub>"); | |
136 } else if (cb.isUncommonTrapStub()) { | |
137 out.println("<UncommonTrap>"); | |
138 } else if (cb.isExceptionStub()) { | |
139 out.println("<ExceptionStub>"); | |
140 } else if (cb.isSafepointStub()) { | |
141 out.println("<SafepointStub>"); | |
142 } else { | |
143 out.println("<Unknown code blob>"); | |
144 } | |
145 } else { | |
146 printUnknown(out); | |
147 } | |
148 } | |
149 // print java frames, if any | |
150 if (names != null && names.length != 0) { | |
151 // print java frame(s) | |
152 for (int i = 0; i < names.length; i++) { | |
153 out.println(names[i]); | |
154 } | |
155 } | |
0 | 156 } |
6163 | 157 f = f.sender(th); |
0 | 158 } |
159 } catch (Exception exp) { | |
160 exp.printStackTrace(); | |
161 // continue, may be we can do a better job for other threads | |
162 } | |
8103 | 163 if (concurrentLocks) { |
0 | 164 JavaThread jthread = (JavaThread) proxyToThread.get(th); |
165 if (jthread != null) { | |
166 concLocksPrinter.print(jthread, out); | |
167 } | |
168 } | |
169 } // for threads | |
170 } else { | |
171 if (getDebugeeType() == DEBUGEE_REMOTE) { | |
172 out.println("remote configuration is not yet implemented"); | |
173 } else { | |
174 out.println("not yet implemented (debugger does not support CDebugger)!"); | |
175 } | |
176 } | |
177 } | |
178 | |
179 public static void main(String[] args) throws Exception { | |
180 PStack t = new PStack(); | |
181 t.start(args); | |
182 t.stop(); | |
183 } | |
184 | |
185 // -- Internals only below this point | |
186 private Map jframeCache; // Map<ThreadProxy, JavaVFrame[]> | |
187 private Map proxyToThread; // Map<ThreadProxy, JavaThread> | |
188 private PrintStream out; | |
189 private boolean verbose; | |
190 private boolean concurrentLocks; | |
191 | |
192 private void initJFrameCache() { | |
193 // cache frames for subsequent reference | |
194 jframeCache = new HashMap(); | |
195 proxyToThread = new HashMap(); | |
196 Threads threads = VM.getVM().getThreads(); | |
197 for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) { | |
198 List tmp = new ArrayList(10); | |
199 try { | |
200 for (JavaVFrame vf = cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) { | |
201 tmp.add(vf); | |
202 } | |
203 } catch (Exception exp) { | |
204 // may be we may get frames for other threads, continue | |
205 // after printing stack trace. | |
206 exp.printStackTrace(); | |
207 } | |
208 JavaVFrame[] jvframes = new JavaVFrame[tmp.size()]; | |
209 System.arraycopy(tmp.toArray(), 0, jvframes, 0, jvframes.length); | |
210 jframeCache.put(cur.getThreadProxy(), jvframes); | |
211 proxyToThread.put(cur.getThreadProxy(), cur); | |
212 } | |
213 } | |
214 | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
215 private void printUnknown(PrintStream out) { |
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
216 out.println("\t????????"); |
0 | 217 } |
218 | |
219 private String[] getJavaNames(ThreadProxy th, Address fp) { | |
220 if (fp == null) { | |
221 return null; | |
222 } | |
223 JavaVFrame[] jvframes = (JavaVFrame[]) jframeCache.get(th); | |
224 if (jvframes == null) return null; // not a java thread | |
225 List names = new ArrayList(10); | |
226 for (int fCount = 0; fCount < jvframes.length; fCount++) { | |
227 JavaVFrame vf = jvframes[fCount]; | |
228 Frame f = vf.getFrame(); | |
229 if (fp.equals(f.getFP())) { | |
230 StringBuffer sb = new StringBuffer(); | |
231 Method method = vf.getMethod(); | |
232 // a special char to identify java frames in output | |
233 sb.append("* "); | |
234 sb.append(method.externalNameAndSignature()); | |
235 sb.append(" bci:" + vf.getBCI()); | |
236 int lineNumber = method.getLineNumberFromBCI(vf.getBCI()); | |
237 if (lineNumber != -1) { | |
238 sb.append(" line:" + lineNumber); | |
239 } | |
240 | |
241 if (verbose) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6163
diff
changeset
|
242 sb.append(" Method*:" + method.getAddress()); |
0 | 243 } |
244 | |
245 if (vf.isCompiledFrame()) { | |
246 sb.append(" (Compiled frame"); | |
247 if (vf.isDeoptimized()) { | |
248 sb.append(" [deoptimized]"); | |
249 } | |
250 } else if (vf.isInterpretedFrame()) { | |
251 sb.append(" (Interpreted frame"); | |
252 } | |
253 if (vf.mayBeImpreciseDbg()) { | |
254 sb.append("; information may be imprecise"); | |
255 } | |
256 sb.append(")"); | |
257 names.add(sb.toString()); | |
258 } | |
259 } | |
260 String[] res = new String[names.size()]; | |
261 System.arraycopy(names.toArray(), 0, res, 0, res.length); | |
262 return res; | |
263 } | |
264 } |