JDK-8344165 : Trace exceptions with a complete call-stack
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2024-11-14
  • Updated: 2025-04-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
Unfortunately, it happens sometimes that applications implement bad practices in the code like swallowing java.lang.Throwable (includes java.lang.VirtualMachineError and java.lang.StackOverflowError) and continue execution with no intention to stop the application. This often results in secondary issues, as JVM is considered broken at this time.
The debug flag "-Xlog:exceptions=log" (or the TraceException flag before it was converted to Unified Logging in JDK9) helps troubleshooting such applications. However, this log prints only the last activation record.
It would be very desirable to get a full call stack instead. Also enable this for a selected exception class only.
E.g. "print full stack only for exceptions of type java.lang.StackOverflowError" or "print full stack for all exceptions that derive from java.lang.VirtualMachineError", etc.
Comments
> IIUC, JVM might be unstable thereafter. There is nothing about throwing a VME that inherently makes the VM "unstable". These exceptions affect the Java code that they pass through, but don't indicate an actual problem with the VM in most cases (OOME, SOE). Even InternalError rarely indicates an actual VM problem and are typically only seen in the code for "should not reach here" type situations.
15-04-2025

Thanks David. The assumption I make here is that JVM clams no guarantee on correct application code execution after VirtualMachineError is thrown. IIUC, JVM might be unstable thereafter. Given this, it would make sense to store call-stack of the very first VirtualMachineError. Is there a different take on this?
14-04-2025

> the added logging "-Xlog:exceptions=info" will show only higher fraction of the stack. I'm not sure what you mean - it will show every frame that is traversed as the exception propagates and with trace level logging you will see where it gets caught. > Do you think we could store the stack-trace of the very first VirtualMachineError in memory for later retrieval by `jcmd` ? Well anything is possible, but would the exception you're interested in necessarily be the first? It is a bit ad-hoc
11-04-2025

That's good to know, it might be useful. Thank you, David! But I have to admit that "-Xlog:exceptions=info" looks very taxing and that requires heavy post-processing (in case of exception avalanche in multithreaded execution). Thinking about an extreme case we've seen in the wild where "application swallows StackOverflowException with try-catch"... the added logging "-Xlog:exceptions=info" will show only higher fraction of the stack. That might still be enough, tho. Do you think we could store the stack-trace of the very first VirtualMachineError in memory for later retrieval by `jcmd` ?
10-04-2025

Simple example: > java Foo Error: Could not find or load main class Foo Caused by: java.lang.ClassNotFoundException: Foo > java -Xlog:exceptions=info Foo | grep "thrown in" thrown in interpreter method <{method} {0x00007f0bd21aebc0} 'loadClass' '(Ljava/lang/String;Z)Ljava/lang/Class;' in 'jdk/internal/loader/BuiltinClassLoader'> thrown in interpreter method <{method} {0x00007f0bd21aff18} 'loadClass' '(Ljava/lang/String;Z)Ljava/lang/Class;' in 'jdk/internal/loader/ClassLoaders$AppClassLoader'> thrown in interpreter method <{method} {0x00007f0bd2175f20} 'loadClass' '(Ljava/lang/String;)Ljava/lang/Class;' in 'java/lang/ClassLoader'> thrown in interpreter method <{method} {0x00007f0bd24984e0} 'forName0' '(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;' in 'java/lang/Class'> thrown in interpreter method <{method} {0x00007f0bd2498650} 'forName' '(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;' in 'java/lang/Class'> thrown in interpreter method <{method} {0x00007f0bd24986a8} 'forName' '(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;' in 'java/lang/Class'> thrown in interpreter method <{method} {0x00007f0bd2412710} 'loadMainClass' '(ILjava/lang/String;)Ljava/lang/Class;' in 'sun/launcher/LauncherHelper'> thrown in interpreter method <{method} {0x00007f0bd24984e0} 'forName0' '(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;' in 'java/lang/Class'> thrown in interpreter method <{method} {0x00007f0bd2498650} 'forName' '(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;' in 'java/lang/Class'> thrown in interpreter method <{method} {0x00007f0bd24986a8} 'forName' '(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;' in 'java/lang/Class'> thrown in interpreter method <{method} {0x00007f0bce024120} 'run' '()Ljava/lang/Class;' in 'java/util/ResourceBundle$3'> Error: Could not find or load main class Foo Caused by: java.lang.ClassNotFoundException: Foo Of course if multiple exceptions are happening in different threads the output is harder to untangle But each "thrown in" line is preceded by a line which identifies the exception instance being thrown, and followed by details about the location and thread e.g. [0.024s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x0000000630812cb8}: Foo> thrown in interpreter method <{method} {0x00007efef61aebc0} 'loadClass' '(Ljava/lang/String;Z)Ljava/lang/Class;' in 'jdk/internal/loader/BuiltinClassLoader'> at bci 19 for thread 0x00007eff74029cd0 (main) [0.024s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x0000000630812cb8}: Foo> thrown in interpreter method <{method} {0x00007efef61aff18} 'loadClass' '(Ljava/lang/String;Z)Ljava/lang/Class;' in 'jdk/internal/loader/ClassLoaders$AppClassLoader'> at bci 36 for thread 0x00007eff74029cd0 (main) [0.024s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x0000000630812cb8}: Foo> thrown in interpreter method <{method} {0x00007efef6175f20} 'loadClass' '(Ljava/lang/String;)Ljava/lang/Class;' in 'java/lang/ClassLoader'> at bci 3 for thread 0x00007eff74029cd0 (main) [0.024s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x0000000630812cb8}: Foo> thrown in interpreter method <{method} {0x00007efef64984e0} 'forName0' '(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;' in 'java/lang/Class'> at bci 0 for thread 0x00007eff74029cd0 (main) [0.024s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x0000000630812cb8}: Foo> thrown in interpreter method <{method} {0x00007efef6498650} 'forName' '(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;' in 'java/lang/Class'> at bci 37 for thread 0x00007eff74029cd0 (main) [0.024s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x0000000630812cb8}: Foo> thrown in interpreter method <{method} {0x00007efef64986a8} 'forName' '(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;' in 'java/lang/Class'> at bci 20 for thread 0x00007eff74029cd0 (main) [0.024s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x0000000630812cb8}: Foo> thrown in interpreter method <{method} {0x00007efef6412710} 'loadMainClass' '(ILjava/lang/String;)Ljava/lang/Class;' in 'sun/launcher/LauncherHelper'> at bci 130 for thread 0x00007eff74029cd0 (main) [0.024s][info][exceptions] Found matching handler for exception of type "java.lang.ClassNotFoundException" in method "loadMainClass" at BCI: 138 [0.032s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x000000063082fd88}: sun/launcher/resources/spi/launcherProvider> (0x000000063082fd88) thrown [open/src/hotspot/share/classfile/systemDictionary.cpp, line 313] for thread 0x00007eff74029cd0 [0.032s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x000000063082fd88}: sun/launcher/resources/spi/launcherProvider> thrown in interpreter method <{method} {0x00007efef64984e0} 'forName0' '(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;' in 'java/lang/Class'> at bci 0 for thread 0x00007eff74029cd0 (main) [0.032s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x000000063082fd88}: sun/launcher/resources/spi/launcherProvider> thrown in interpreter method <{method} {0x00007efef6498650} 'forName' '(Ljava/lang/String;ZLjava/lang/ClassLoader;Ljava/lang/Class;)Ljava/lang/Class;' in 'java/lang/Class'> at bci 37 for thread 0x00007eff74029cd0 (main) [0.032s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x000000063082fd88}: sun/launcher/resources/spi/launcherProvider> thrown in interpreter method <{method} {0x00007efef64986a8} 'forName' '(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;' in 'java/lang/Class'> at bci 20 for thread 0x00007eff74029cd0 (main) [0.032s][info][exceptions] Exception <a 'java/lang/ClassNotFoundException'{0x000000063082fd88}: sun/launcher/resources/spi/launcherProvider> thrown in interpreter method <{method} {0x00007efef2022c80} 'run' '()Ljava/lang/Class;' in 'java/util/ResourceBundle$3'> at bci 9 for thread 0x00007eff74029cd0 (main) [0.032s][info][exceptions] Found matching handler for exception of type "java.lang.ClassNotFoundException" in method "run" at BCI: 29 Error: Could not find or load main class Foo Caused by: java.lang.ClassNotFoundException: Foo
10-04-2025

-Xlog:exceptions does show the complete stack, just not in the direct grouping that is seen with a programmatic stacktrace. You will see various level of detail using info,debug, and trace levels, which show you which activation records (including VM native code) are examined for catch blocks as the exception propagates. It does not (perhaps "may not" ??) have the source information however.
10-04-2025

Runtime Triage: This is not on our current list of priorities. We will consider this feature if we receive additional customer requirements.
09-01-2025

TraceException flag was replaced with unified logging: JDK-8141211. I added a link.
15-11-2024