views:

1137

answers:

6

I am thinking of creating a debug tool for my Java application.

I am wondering if it is possible to get a stack trace, just like Exception.printStackTrace() but without actually throwing an exception?

My goal is to in any given method, dump a stack to see who the method caller is.

Any replies or thoughts concerning this would be really helpful :)

+16  A: 

Yes, simply use

Thread.dumpStack()
Rob Di Marco
... which creates a new Exception, and calls `printStackTrace()` on it.
erickson
...but doesn't throw it.
Rob
+2  A: 

You can get a stack trace like this:

Throwable t = new Throwable();
t.printStackTrace();

If you want to access the frame, you can use t.getStackTrace() to get an array of stack frames.

Be aware that this stacktrace (just like any other) may be missing some frames if the hotspot compiler has been busy optimizing things.

Gerco Dries
+21  A: 

You can also try Thread.getAllStackTraces() to get a map of stack traces for all the threads that are alive

Ram
+1, definitely useful if he wants to analyze the stack trace!
Adam Paynter
+3  A: 

If you want the trace for just the current thread (rather than all the threads in the system, as Ram's suggestion does), do:

Thread.currentThread().getStackTrace()

To find the caller, do:

private String getCallingMethodName() {
    StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4];
    return callingFrame.getMethodName();
}

And call that method from within the method that needs to know who its caller is. However, a word of warning: the index of the calling frame within the list could vary according to the JVM! It all depends on how many layers of calls there are within getStackTrace before you hit the point where the trace is generated. A more robust solution would be to get the trace, and iterate over it looking for the frame for getCallingMethodName, then take two steps further up to find the true caller.

Tom Anderson
A: 

HPROF Java Profiler

You don't even have to do this in the code. You can attach the Java HPROF to your process and at any point hit Control-\ to output heap dump, running threads, etc . . . without mucking up your application code. This is a bit outdated, Java 6 comes with the GUI jconsole, but I still find HPROF to be very useful.

Gandalf
+1  A: 

You can also send a signal to the JVM to execute Thread.getAllStackTraces() on a running Java process by sending a QUIT signal to the process.

On Unix/Linux use:

kill -QUIT process_id, where process_id is the process number of your Java program.

On Windows, you can press Ctrl-Break in the application, although you usually won't see this unless you're running a console process.

JDK6 introduced another option, the jstack command, which will display the stack from any running JDK6 process on your computer:

jstack [-l] <pid>

These options are very useful for applications which are running in a production environment and cannot be modified easily. They're especially useful for diagnosing runtime deadlocks or performance problems.

http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/ http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html

Andrew Newdigate