comparison agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children a5838065ab24
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
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 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
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.*;
35
36 public class PStack extends Tool {
37 // in non-verbose mode, methodOops are not printed in java frames
38 public PStack(boolean v, boolean concurrentLocks) {
39 this.verbose = v;
40 this.concurrentLocks = concurrentLocks;
41 }
42
43 public PStack() {
44 this(true, true);
45 }
46
47 public void run() {
48 run(System.out);
49 }
50
51 public void run(PrintStream out) {
52 Debugger dbg = getAgent().getDebugger();
53 run(out, dbg, getAgent().isJavaMode());
54 }
55
56 public void run(PrintStream out, Debugger dbg) {
57 run(out, dbg, true);
58 }
59
60 private void run(PrintStream out, Debugger dbg, final boolean isJava) {
61 CDebugger cdbg = dbg.getCDebugger();
62 if (cdbg != null) {
63 ConcurrentLocksPrinter concLocksPrinter = null;
64 if (isJava) {
65 // compute and cache java Vframes.
66 initJFrameCache();
67 if (concurrentLocks) {
68 concLocksPrinter = new ConcurrentLocksPrinter();
69 }
70 // print Java level deadlocks
71 try {
72 DeadlockDetector.print(out);
73 } catch (Exception exp) {
74 out.println("can't print deadlock information: " + exp.getMessage());
75 }
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();
90 if (sym != null) {
91 String name = sym.getName();
92 if (cdbgCanDemangle) {
93 name = cdbg.demangle(name);
94 }
95 out.print(pc + "\t" + name);
96 long diff = sym.getOffset();
97 if (diff != 0L) {
98 out.print(" + 0x" + Long.toHexString(diff));
99 }
100 out.println();
101 } else {
102 if (isJava) {
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 out.print(pc + "\t");
124 CodeBlob cb = c.findBlobUnsafe(pc);
125 if (cb.isNMethod()) {
126 names = getJavaNames(th, f.localVariableBase());
127 // just print compiled code, if can't determine method
128 if (names == null || names.length == 0) {
129 out.println("<Unknown compiled code>");
130 }
131 } else if (cb.isBufferBlob()) {
132 out.println("<StubRoutines>");
133 } else if (cb.isRuntimeStub()) {
134 out.println("<RuntimeStub>");
135 } else if (cb.isDeoptimizationStub()) {
136 out.println("<DeoptimizationStub>");
137 } else if (cb.isUncommonTrapStub()) {
138 out.println("<UncommonTrap>");
139 } else if (cb.isExceptionStub()) {
140 out.println("<ExceptionStub>");
141 } else if (cb.isSafepointStub()) {
142 out.println("<SafepointStub>");
143 } else {
144 out.println("<Unknown code blob>");
145 }
146 } else {
147 printUnknown(out,pc);
148 }
149 }
150 // print java frames, if any
151 if (names != null && names.length != 0) {
152 // print java frame(s)
153 for (int i = 0; i < names.length; i++) {
154 out.println(pc + "\t" + names[i]);
155 }
156 }
157 } else {
158 printUnknown(out,pc);
159 }
160 }
161 f = f.sender();
162 }
163 } catch (Exception exp) {
164 exp.printStackTrace();
165 // continue, may be we can do a better job for other threads
166 }
167 if (isJava && concurrentLocks) {
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 protected boolean requiresVM() {
184 return false;
185 }
186
187 public static void main(String[] args) throws Exception {
188 PStack t = new PStack();
189 t.start(args);
190 t.stop();
191 }
192
193 // -- Internals only below this point
194 private Map jframeCache; // Map<ThreadProxy, JavaVFrame[]>
195 private Map proxyToThread; // Map<ThreadProxy, JavaThread>
196 private PrintStream out;
197 private boolean verbose;
198 private boolean concurrentLocks;
199
200 private void initJFrameCache() {
201 // cache frames for subsequent reference
202 jframeCache = new HashMap();
203 proxyToThread = new HashMap();
204 Threads threads = VM.getVM().getThreads();
205 for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) {
206 List tmp = new ArrayList(10);
207 try {
208 for (JavaVFrame vf = cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
209 tmp.add(vf);
210 }
211 } catch (Exception exp) {
212 // may be we may get frames for other threads, continue
213 // after printing stack trace.
214 exp.printStackTrace();
215 }
216 JavaVFrame[] jvframes = new JavaVFrame[tmp.size()];
217 System.arraycopy(tmp.toArray(), 0, jvframes, 0, jvframes.length);
218 jframeCache.put(cur.getThreadProxy(), jvframes);
219 proxyToThread.put(cur.getThreadProxy(), cur);
220 }
221 }
222
223 private void printUnknown(PrintStream out, Address pc) {
224 out.println(pc + "\t????????");
225 }
226
227 private String[] getJavaNames(ThreadProxy th, Address fp) {
228 if (fp == null) {
229 return null;
230 }
231 JavaVFrame[] jvframes = (JavaVFrame[]) jframeCache.get(th);
232 if (jvframes == null) return null; // not a java thread
233 List names = new ArrayList(10);
234 for (int fCount = 0; fCount < jvframes.length; fCount++) {
235 JavaVFrame vf = jvframes[fCount];
236 Frame f = vf.getFrame();
237 if (fp.equals(f.getFP())) {
238 StringBuffer sb = new StringBuffer();
239 Method method = vf.getMethod();
240 // a special char to identify java frames in output
241 sb.append("* ");
242 sb.append(method.externalNameAndSignature());
243 sb.append(" bci:" + vf.getBCI());
244 int lineNumber = method.getLineNumberFromBCI(vf.getBCI());
245 if (lineNumber != -1) {
246 sb.append(" line:" + lineNumber);
247 }
248
249 if (verbose) {
250 sb.append(" methodOop:" + method.getHandle());
251 }
252
253 if (vf.isCompiledFrame()) {
254 sb.append(" (Compiled frame");
255 if (vf.isDeoptimized()) {
256 sb.append(" [deoptimized]");
257 }
258 } else if (vf.isInterpretedFrame()) {
259 sb.append(" (Interpreted frame");
260 }
261 if (vf.mayBeImpreciseDbg()) {
262 sb.append("; information may be imprecise");
263 }
264 sb.append(")");
265 names.add(sb.toString());
266 }
267 }
268 String[] res = new String[names.size()];
269 System.arraycopy(names.toArray(), 0, res, 0, res.length);
270 return res;
271 }
272 }