What happens when we say e.printStackTrace();? Here e is any Exception. Does it stop the normal execution and actually remove the activation records from the thread stack to give the stack trace of the exception? Is it a good idea to use it in applications?
- 1The stack trace is the thread stack when the exception was created, not where it was printed/logged.Peter Lawrey– Peter Lawrey2011-02-10 14:30:04 +00:00Commented Feb 10, 2011 at 14:30
6 Answers
It just prints stack trace that is already held by exception object to STDERR. No side effects.
2 Comments
fillInStackTrace which already has the "cost" of recording the stack. It's just the "cost" of pulling it from that native place into StackTraceElement objects that is bypassed.Does it stop the normal execution
No.
and actually remove the activation records from the thread stack to give the stack trace of the exception?
No.
The information has already been captured. This happens in the constructors for Throwable ; i.e. when you new an exception, not when you throw it. The Throwable constructor calls the fillInStackTrace() native method which takes a snapshot of the stack and stores the resulting StackTraceElement[] in a private variable that is used later when printing the stack trace.
(For the record, this is specified in the javadoc for the constructors of Throwable.
Is it a good idea to use it in applications?
Well it is rather expensive and can produce a lot of output. But if you need the stack trace for diagnostic purposes ... do it.
2 Comments
fillInStackTrace() is (in the broad sense) doing the work. Besides, the private native method call is a platform specific implementation detail.e.printStackTrace();
e is instance of Throwable
This method prints a stack trace for this Throwable object on the error output stream that is the value of the field System.err
1 Comment
There's nothing particularly clever going on. The Exception object contains a list of StackTraceElements, and it simply dumps them to stderr when the above is called.
1 Comment
As already said, there's no side effects and you won't introduce any issues per-se with using it in production code. I wouldn't really advise it (in production code) however, simply because in most applications it's much better to use a logger to get finer control of exactly what's logged and where it's logged to.
Comments
The stack-trace is loaded via fillInStackTrace which is a native method that is called in the constructor of Throwable. (Neat tip: this method can be overloaded as a NOP for "signal exceptions" which do not need the rather expensive call to get the stack).
The "freeze" of the stack trace already exists for the Throwable object when it is "caught".
As per the code for java.lang.Throwable shows that fillInStackTrace is called as the first action of the constructor. The array of StackTraceElement is for serialization support (this can also be set manually) and as a lazy cache.
Even though that fillInStackTrace captures the trace it is not loaded into Java objects -- I suppose this allows the implementation to keep it "cheap" -- until it needs to be accessed as a sequence of StackTraceElement objects (e.g. for printStackTrace which is done in Java code). The code for Throwable shows this better than I can explain :-)
Happy coding.