--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java 2020-03-20 18:40:53.567982100 +0900 +++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java 2020-03-20 18:40:52.745977700 +0900 @@ -36,6 +36,7 @@ Address libptr = dbg.findLibPtrByAddress(rip); Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP); DwarfParser dwarf = null; + boolean unsupportedDwarf = false; if (libptr != null) { // Native frame try { @@ -47,20 +48,29 @@ : context.getRegisterAsAddress(dwarf.getCFARegister()) .addOffsetTo(dwarf.getCFAOffset()); } catch (DebuggerException e) { - // Bail out to Java frame case + if (dwarf != null) { + // DWARF processing should succeed when the frame is native + // but it might fail if CIE has language personality routine + // and/or LSDA. + dwarf = null; + unsupportedDwarf = true; + } else { + throw e; + } } } return (cfa == null) ? null - : new LinuxAMD64CFrame(dbg, cfa, rip, dwarf); + : new LinuxAMD64CFrame(dbg, cfa, rip, dwarf, !unsupportedDwarf); } - private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) { + private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf, boolean possibleNext) { super(dbg.getCDebugger()); this.cfa = cfa; this.rip = rip; this.dbg = dbg; this.dwarf = dwarf; + this.possibleNext = possibleNext; } // override base class impl to avoid ELF parsing @@ -123,9 +133,21 @@ return isValidFrame(nextCFA, context) ? nextCFA : null; } - private DwarfParser getNextDwarf(Address nextPC) { - DwarfParser nextDwarf = null; + @Override + public CFrame sender(ThreadProxy thread) { + if (!possibleNext) { + return null; + } + + ThreadContext context = thread.getContext(); + Address nextPC = getNextPC(dwarf != null); + if (nextPC == null) { + return null; + } + + DwarfParser nextDwarf = null; + boolean unsupportedDwarf = false; if ((dwarf != null) && dwarf.isIn(nextPC)) { nextDwarf = dwarf; } else { @@ -140,25 +162,20 @@ } if (nextDwarf != null) { - nextDwarf.processDwarf(nextPC); - } - - return nextDwarf; - } - - @Override - public CFrame sender(ThreadProxy thread) { - ThreadContext context = thread.getContext(); - - Address nextPC = getNextPC(dwarf != null); - if (nextPC == null) { - return null; + try { + nextDwarf.processDwarf(nextPC); + } catch (DebuggerException e) { + // DWARF processing should succeed when the frame is native + // but it might fail if CIE has language personality routine + // and/or LSDA. + nextDwarf = null; + unsupportedDwarf = true; + } } - DwarfParser nextDwarf = getNextDwarf(nextPC); Address nextCFA = getNextCFA(nextDwarf, context); - return isValidFrame(nextCFA, context) ? new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf) - : null; + LinuxAMD64CFrame nextFrame = new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf, !unsupportedDwarf); + return isValidFrame(nextCFA, context) ? nextFrame : null; } // package/class internals only @@ -167,4 +184,5 @@ private Address cfa; private LinuxDebugger dbg; private DwarfParser dwarf; + private boolean possibleNext; }