JDK-8035983 : Fix "Native frames:" in crash report (hs_err file)
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2014-02-28
  • Updated: 2018-01-04
  • Resolved: 2014-03-06
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.
JDK 8 JDK 9
8u20Fixed 9 b06Fixed
Related Reports
Relates :  
Description
We don't print whole stack if native frames intermix with compiled java frames in Java thread (on x86 fp is used by compiled code).

Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x1e28428]  void VMError::report(outputStream*)+0x1478
V  [libjvm.so+0x1e29dd4]  void VMError::report_and_die()+0x6b4
V  [libjvm.so+0x14ad9ba]  void report_vm_error(const char*,int,const char*,const char*)+0x9a
V  [libjvm.so+0x1b6ccf5]  void ObjectMonitor::exit(bool,Thread*)+0x125
V  [libjvm.so+0x1d41cda]  void ObjectSynchronizer::fast_exit(oopDesc*,BasicLock*,Thread*)+0x38a
V  [libjvm.so+0x1d41fba]  void ObjectSynchronizer::slow_exit(oopDesc*,BasicLock*,Thread*)+0x2a
V  [libjvm.so+0x1caa13f]  void SharedRuntime::complete_monitor_unlocking_C(oopDesc*,BasicLock*)+0x27f

The next changes seem fixed the problem:

src/share/vm/utilities/vmError.cpp
@@ -590,15 +590,17 @@
           while (count++ < StackPrintLimit) {
              fr.print_on_error(st, buf, sizeof(buf));
              st->cr();
+             // Catch very first native frame by using stack address.
+             if ((address)(fr.sp() + 4) >= _thread->stack_base()) break;
+
              // Compiled code may use EBP register on x86 so it looks like
-             // non-walkable C frame. Use frame.sender() for java frames.
+             // non-walkable C frame. Use frame.sender() for java threads.
              if (_thread && _thread->is_Java_thread() && fr.is_java_frame()) {
                RegisterMap map((JavaThread*)_thread, false); // No update
                fr = fr.sender(&map);
-               continue;
+             } else {
+               fr = os::get_sender_for_C_frame(&fr);
              }
-             if (os::is_first_C_frame(&fr)) break;
-             fr = os::get_sender_for_C_frame(&fr);
           }
 
           if (count > StackPrintLimit) {

Instead of using os::is_first_C_frame() which produces incorrect result for compiled java frames I am suggesting to look on frame's stack pointer relative to stack's base.

Comments
noreg-hard: it is hard to write test which checks call stack output during crash, some platforms does not always produce it (separate issue).
13-03-2014