--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java 2019-12-15 10:42:32.936932500 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java 2019-12-15 10:42:32.248618000 +0900 @@ -90,11 +90,29 @@ return new LinuxX86CFrame(dbg, ebp, pc); } else if (cpu.equals("amd64")) { AMD64ThreadContext context = (AMD64ThreadContext) thread.getContext(); - Address rbp = context.getRegisterAsAddress(AMD64ThreadContext.RBP); - if (rbp == null) return null; Address pc = context.getRegisterAsAddress(AMD64ThreadContext.RIP); if (pc == null) return null; - return new LinuxAMD64CFrame(dbg, rbp, pc); + + long libptr = dbg.findLibPtrByAddress(pc); + Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP); + DwarfParser dwarf = null; + + if (libptr != 0L) { // Native frame + try { + dwarf = new DwarfParser(libptr); + dwarf.processDwarf(pc); + cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) && + !dwarf.isBPOffsetAvailable()) + ? context.getRegisterAsAddress(AMD64ThreadContext.RBP) + : context.getRegisterAsAddress(dwarf.getCFARegister()) + .addOffsetTo(dwarf.getCFAOffset()); + } catch (DebuggerException e) { + // Bail out to Java frame case + } + } + + return (cfa == null) ? null + : new LinuxAMD64CFrame(dbg, cfa, pc, dwarf); } else if (cpu.equals("sparc")) { SPARCThreadContext context = (SPARCThreadContext) thread.getContext(); Address sp = context.getRegisterAsAddress(SPARCThreadContext.R_SP);