< prev index next >

src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/amd64/LinuxAMD64CFrame.java

Print this page

        

@@ -36,33 +36,41 @@
       Address libptr = dbg.findLibPtrByAddress(rip);
       Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
       DwarfParser dwarf = null;
 
       if (libptr != null) { // Native frame
-        try {
           dwarf = new DwarfParser(libptr);
+        try {
           dwarf.processDwarf(rip);
+        } catch (DebuggerException e) {
+          // DWARF processing should succeed when the frame is native
+          // but it might fail if Common Information Entry (CIE) has language
+          // personality routine and/or Language Specific Data Area (LSDA).
+          return new LinuxAMD64CFrame(dbg, cfa, rip, dwarf, true);
+        }
           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, rip, dwarf);
    }
 
    private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) {
+      this(dbg, cfa, rip, dwarf, false);
+   }
+
+   private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf, boolean lastFrame) {
       super(dbg.getCDebugger());
       this.cfa = cfa;
       this.rip = rip;
       this.dbg = dbg;
       this.dwarf = dwarf;
+      this.lastFrame = lastFrame;
    }
 
    // override base class impl to avoid ELF parsing
    public ClosestSymbol closestSymbolToPC() {
       // try native lookup in debugger.

@@ -121,11 +129,23 @@
      }
 
      return isValidFrame(nextCFA, context) ? nextCFA : null;
    }
 
-   private DwarfParser getNextDwarf(Address nextPC) {
+   @Override
+   public CFrame sender(ThreadProxy thread) {
+     if (lastFrame) {
+       return null;
+     }
+
+     ThreadContext context = thread.getContext();
+
+     Address nextPC = getNextPC(dwarf != null);
+     if (nextPC == null) {
+       return null;
+     }
+
      DwarfParser nextDwarf = null;
 
      if ((dwarf != null) && dwarf.isIn(nextPC)) {
        nextDwarf = dwarf;
      } else {

@@ -138,26 +158,20 @@
          }
        }
      }
 
      if (nextDwarf != null) {
+       try {
        nextDwarf.processDwarf(nextPC);
+       } catch (DebuggerException e) {
+         // DWARF processing should succeed when the frame is native
+         // but it might fail if Common Information Entry (CIE) has language
+         // personality routine and/or Language Specific Data Area (LSDA).
+         return new LinuxAMD64CFrame(dbg, null, nextPC, nextDwarf, 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;
    }
 

@@ -165,6 +179,7 @@
    private static final int ADDRESS_SIZE = 8;
    private Address rip;
    private Address cfa;
    private LinuxDebugger dbg;
    private DwarfParser dwarf;
+   private boolean lastFrame;
 }
< prev index next >