1/*
2 * Copyright (c) 2002, 2017, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25package sun.jvm.hotspot.tools;
26
27import sun.jvm.hotspot.debugger.*;
28import sun.jvm.hotspot.runtime.*;
29import sun.jvm.hotspot.oops.*;
30
31/** Traverses and prints the stack traces for all Java threads in the
32 * remote VM */
33public class StackTrace extends Tool {
34    // in non-verbose mode pc, sp and Method* are not printed
35    public StackTrace(boolean v, boolean concurrentLocks) {
36        this.verbose = v;
37        this.concurrentLocks = concurrentLocks;
38    }
39
40    public StackTrace() {
41        this(true, true);
42    }
43
44    public void run() {
45        run(System.out);
46    }
47
48    public StackTrace(JVMDebugger d) {
49        super(d);
50    }
51
52    public StackTrace(JVMDebugger d, boolean v, boolean concurrentLocks) {
53        super(d);
54        this.verbose = v;
55        this.concurrentLocks = concurrentLocks;
56    }
57
58    public void run(java.io.PrintStream tty) {
59        // Ready to go with the database...
60        try {
61            // print deadlock information before stack trace
62            DeadlockDetector.print(tty);
63        } catch (Exception exp) {
64            exp.printStackTrace();
65            tty.println("Can't print deadlocks:" + exp.getMessage());
66        }
67
68        try {
69            ConcurrentLocksPrinter concLocksPrinter = null;
70            if (concurrentLocks) {
71                concLocksPrinter = new ConcurrentLocksPrinter();
72            }
73            Threads threads = VM.getVM().getThreads();
74            int i = 1;
75            for (JavaThread cur = threads.first(); cur != null; cur = cur.next(), i++) {
76                if (cur.isJavaThread()) {
77                    cur.printThreadInfoOn(tty);
78                    try {
79                        for (JavaVFrame vf = cur.getLastJavaVFrameDbg(); vf != null; vf = vf.javaSender()) {
80                            Method method = vf.getMethod();
81                            tty.print(" - " + method.externalNameAndSignature() +
82                            " @bci=" + vf.getBCI());
83
84                            int lineNumber = method.getLineNumberFromBCI(vf.getBCI());
85                            if (lineNumber != -1) {
86                                tty.print(", line=" + lineNumber);
87                            }
88
89                            if (verbose) {
90                                Address pc = vf.getFrame().getPC();
91                                if (pc != null) {
92                                    tty.print(", pc=" + pc);
93                                }
94
95                                tty.print(", Method*=" + method.getAddress());
96                            }
97
98                            if (vf.isCompiledFrame()) {
99                                tty.print(" (Compiled frame");
100                                if (vf.isDeoptimized()) {
101                                  tty.print(" [deoptimized]");
102                                }
103                            }
104                            if (vf.isInterpretedFrame()) {
105                                tty.print(" (Interpreted frame");
106                            }
107                            if (vf.mayBeImpreciseDbg()) {
108                                tty.print("; information may be imprecise");
109                            }
110
111                            tty.println(")");
112                        }
113                    } catch (Exception e) {
114                        tty.println("Error occurred during stack walking:");
115                        e.printStackTrace();
116                    }
117                    tty.println();
118                    if (concurrentLocks) {
119                        concLocksPrinter.print(cur, tty);
120                    }
121                    tty.println();
122              }
123          }
124      }
125      catch (AddressException e) {
126        System.err.println("Error accessing address 0x" + Long.toHexString(e.getAddress()));
127        e.printStackTrace();
128      }
129   }
130
131   public static void main(String[] args) {
132      StackTrace st = new StackTrace();
133      st.execute(args);
134   }
135
136   private boolean verbose;
137   private boolean concurrentLocks;
138}
139