< 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 >