Is there a way to dump a stack trace without throwing an exception in java?
Solution 1
You can also try Thread.getAllStackTraces()
to get a map of stack traces for all the threads that are alive.
Solution 2
Yes, simply use
Thread.dumpStack()
Solution 3
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.
Solution 4
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.
Solution 5
Notice that Thread.dumpStack() actually throws an exception:
new Exception("Stack trace").printStackTrace();
Related videos on Youtube
corgrath
Updated on May 02, 2020Comments
-
corgrath almost 4 years
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.
-
Daniel almost 13 yearsSo just create a new Exception on your own and use [1] as the index!
-
Tom Anderson almost 13 yearsThe title of this question says "without throwing an exception". Granted, you suggest creating the exception but not throwing it, but i still think that's not in the spirit of the question.
-
Daniel almost 13 yearsOf course it is. Creating an Exception is the most lowlevel way to get a stacktrace. Even your Thread.currentThread().getStackTrace() does it, but my way does it faster :).
-
Tyler about 10 yearsIt creates an exception, but doesn't throw it.
-
bruno almost 9 yearsThat is the answer that actually addresses the question.
-
Admin over 8 yearsI like this answer because it offers me the opportunity to direct the output. I can replace
t.printStackTrace
witht.printStackTrace(System.out)
. -
Admin over 8 yearsIn one line:
new Throwable().printStackTrace(System.out);
-
Sam over 6 yearsThis should be the accepted answer. It is simple and straight forward! Thanks for sharing
-
MitchBroadhead about 6 yearsand it is easy to send to java.util.Logger
log.log(Level.SEVERE, "Failed to do something", new Throwable());
-
mike rodent about 6 years@Daniel There's another consideration: with many testing frameworks, e.g. Spock, just creating an Exception (without throwing it) will be enough for the framework to pick up on: the test will then consider that an Exception has "occurred" and the test will end, with a fail.
-
Daniel about 6 years@mikerodent: Are you sure? Spock would have to use agents to do that. But anyway, because I just needed to calling class I used Reflection.getCallerClass(2) in an utility function. You won't get the function and line number that way, thought.
-
deLock almost 6 yearsVery simple and elegant. This should have been the accepted answer.
-
JohnK over 5 yearsFwiw, the source of this method:
public static void dumpStack() { new Exception("Stack trace").printStackTrace(); }
-
mike rodent almost 4 yearsThis is by far the best answer to the question if you are happy with outputting to
stderr
, which seems to be the implication of the question.