Mercurial > hg > graal-compiler
annotate agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java @ 218:a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
Summary: Fixed stack walking code in sparc to start frame walk from last_java_sp.
Reviewed-by: sgoldman
author | swamyv |
---|---|
date | Tue, 24 Jun 2008 21:37:10 -0700 |
parents | a61af66fc99e |
children | c18cbe5936b8 |
rev | line source |
---|---|
0 | 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(); | |
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 { | |
103 if (isJava) { | |
104 // look for one or more java frames | |
105 String[] names = null; | |
106 // check interpreter frame | |
107 Interpreter interp = VM.getVM().getInterpreter(); | |
108 if (interp.contains(pc)) { | |
109 names = getJavaNames(th, f.localVariableBase()); | |
110 // print codelet name if we can't determine method | |
111 if (names == null || names.length == 0) { | |
112 out.print("<interpreter> "); | |
113 InterpreterCodelet ic = interp.getCodeletContaining(pc); | |
114 if (ic != null) { | |
115 String desc = ic.getDescription(); | |
116 if (desc != null) out.print(desc); | |
117 } | |
118 out.println(); | |
119 } | |
120 } else { | |
121 // look for known code blobs | |
122 CodeCache c = VM.getVM().getCodeCache(); | |
123 if (c.contains(pc)) { | |
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 { | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
147 printUnknown(out); |
0 | 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++) { | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
154 out.println(names[i]); |
0 | 155 } |
156 } | |
157 } else { | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
158 printUnknown(out); |
0 | 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 | |
218
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
223 private void printUnknown(PrintStream out) { |
a5838065ab24
6620329: jstack prints double native methods on Solaris/sparc
swamyv
parents:
0
diff
changeset
|
224 out.println("\t????????"); |
0 | 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 } |