< prev index next >
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java
Print this page
@@ -34,10 +34,11 @@
public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rip, ThreadContext context) {
Address libptr = dbg.findLibPtrByAddress(rip);
Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
DwarfParser dwarf = null;
+ boolean unsupportedDwarf = false;
if (libptr != null) { // Native frame
try {
dwarf = new DwarfParser(libptr);
dwarf.processDwarf(rip);
@@ -45,24 +46,33 @@
!dwarf.isBPOffsetAvailable())
? context.getRegisterAsAddress(AMD64ThreadContext.RBP)
: 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
public ClosestSymbol closestSymbolToPC() {
// try native lookup in debugger.
@@ -121,13 +131,25 @@
}
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 {
Address libptr = dbg.findLibPtrByAddress(nextPC);
if (libptr != null) {
@@ -138,33 +160,29 @@
}
}
}
if (nextDwarf != 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;
}
-
- return nextDwarf;
- }
-
- @Override
- public CFrame sender(ThreadProxy thread) {
- ThreadContext context = thread.getContext();
-
- Address nextPC = getNextPC(dwarf != null);
- if (nextPC == null) {
- return null;
}
- 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
private static final int ADDRESS_SIZE = 8;
private Address rip;
private Address cfa;
private LinuxDebugger dbg;
private DwarfParser dwarf;
+ private boolean possibleNext;
}
< prev index next >