< prev index next >

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

Print this page




  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.debugger.linux.amd64;
  26 
  27 import sun.jvm.hotspot.debugger.*;
  28 import sun.jvm.hotspot.debugger.amd64.*;
  29 import sun.jvm.hotspot.debugger.linux.*;
  30 import sun.jvm.hotspot.debugger.cdbg.*;
  31 import sun.jvm.hotspot.debugger.cdbg.basic.*;
  32 
  33 final public class LinuxAMD64CFrame extends BasicCFrame {
  34 
  35    public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rip, ThreadContext context) {
  36       Address libptr = dbg.findLibPtrByAddress(rip);
  37       Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
  38       DwarfParser dwarf = null;

  39 
  40       if (libptr != null) { // Native frame
  41         try {
  42           dwarf = new DwarfParser(libptr);
  43           dwarf.processDwarf(rip);
  44           cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) &&
  45                  !dwarf.isBPOffsetAvailable())
  46                     ? context.getRegisterAsAddress(AMD64ThreadContext.RBP)
  47                     : context.getRegisterAsAddress(dwarf.getCFARegister())
  48                              .addOffsetTo(dwarf.getCFAOffset());
  49         } catch (DebuggerException e) {
  50           // Bail out to Java frame case








  51         }
  52       }
  53 
  54       return (cfa == null) ? null
  55                            : new LinuxAMD64CFrame(dbg, cfa, rip, dwarf);
  56    }
  57 
  58    private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) {
  59       super(dbg.getCDebugger());
  60       this.cfa = cfa;
  61       this.rip = rip;
  62       this.dbg = dbg;
  63       this.dwarf = dwarf;

  64    }
  65 
  66    // override base class impl to avoid ELF parsing
  67    public ClosestSymbol closestSymbolToPC() {
  68       // try native lookup in debugger.
  69       return dbg.lookup(dbg.getAddressValue(pc()));
  70    }
  71 
  72    public Address pc() {
  73       return rip;
  74    }
  75 
  76    public Address localVariableBase() {
  77       return cfa;
  78    }
  79 
  80    private Address getNextPC(boolean useDwarf) {
  81      try {
  82        long offs = useDwarf ? dwarf.getReturnAddressOffsetFromCFA()
  83                             : ADDRESS_SIZE;


 106          if (!dwarf.isBPOffsetAvailable() && // Use RBP as CFA
 107              (nextCFAReg == AMD64ThreadContext.RBP) &&
 108              (nextCFAReg != dwarf.getCFARegister())) {
 109            nextCFA = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
 110            if (nextCFA == null) {
 111              return null;
 112            }
 113            nextCFA = nextCFA.getAddressAt(0);
 114          } else {
 115            nextCFA = cfa.getAddressAt(dwarf.getBasePointerOffsetFromCFA());
 116          }
 117        }
 118        if (nextCFA != null) {
 119          nextCFA = nextCFA.addOffsetTo(-nextDwarf.getBasePointerOffsetFromCFA());
 120        }
 121      }
 122 
 123      return isValidFrame(nextCFA, context) ? nextCFA : null;
 124    }
 125 
 126    private DwarfParser getNextDwarf(Address nextPC) {
 127      DwarfParser nextDwarf = null;










 128 


 129      if ((dwarf != null) && dwarf.isIn(nextPC)) {
 130        nextDwarf = dwarf;
 131      } else {
 132        Address libptr = dbg.findLibPtrByAddress(nextPC);
 133        if (libptr != null) {
 134          try {
 135            nextDwarf = new DwarfParser(libptr);
 136          } catch (DebuggerException e) {
 137            // Bail out to Java frame
 138          }
 139        }
 140      }
 141 
 142      if (nextDwarf != null) {

 143        nextDwarf.processDwarf(nextPC);






 144      }
 145 
 146      return nextDwarf;
 147    }
 148 
 149    @Override
 150    public CFrame sender(ThreadProxy thread) {
 151      ThreadContext context = thread.getContext();
 152 
 153      Address nextPC = getNextPC(dwarf != null);
 154      if (nextPC == null) {
 155        return null;
 156      }
 157 
 158      DwarfParser nextDwarf = getNextDwarf(nextPC);
 159      Address nextCFA = getNextCFA(nextDwarf, context);
 160      return isValidFrame(nextCFA, context) ? new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf)
 161                                            : null;
 162    }
 163 
 164    // package/class internals only
 165    private static final int ADDRESS_SIZE = 8;
 166    private Address rip;
 167    private Address cfa;
 168    private LinuxDebugger dbg;
 169    private DwarfParser dwarf;

 170 }


  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package sun.jvm.hotspot.debugger.linux.amd64;
  26 
  27 import sun.jvm.hotspot.debugger.*;
  28 import sun.jvm.hotspot.debugger.amd64.*;
  29 import sun.jvm.hotspot.debugger.linux.*;
  30 import sun.jvm.hotspot.debugger.cdbg.*;
  31 import sun.jvm.hotspot.debugger.cdbg.basic.*;
  32 
  33 final public class LinuxAMD64CFrame extends BasicCFrame {
  34 
  35    public static LinuxAMD64CFrame getTopFrame(LinuxDebugger dbg, Address rip, ThreadContext context) {
  36       Address libptr = dbg.findLibPtrByAddress(rip);
  37       Address cfa = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
  38       DwarfParser dwarf = null;
  39       boolean unsupportedDwarf = false;
  40 
  41       if (libptr != null) { // Native frame
  42         try {
  43           dwarf = new DwarfParser(libptr);
  44           dwarf.processDwarf(rip);
  45           cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) &&
  46                  !dwarf.isBPOffsetAvailable())
  47                     ? context.getRegisterAsAddress(AMD64ThreadContext.RBP)
  48                     : context.getRegisterAsAddress(dwarf.getCFARegister())
  49                              .addOffsetTo(dwarf.getCFAOffset());
  50         } catch (DebuggerException e) {
  51           if (dwarf != null) {
  52             // DWARF processing should succeed when the frame is native
  53             // but it might fail if CIE has language personality routine
  54             // and/or LSDA.
  55             dwarf = null;
  56             unsupportedDwarf = true;
  57           } else {
  58             throw e;
  59           }
  60         }
  61       }
  62 
  63       return (cfa == null) ? null
  64                            : new LinuxAMD64CFrame(dbg, cfa, rip, dwarf, !unsupportedDwarf);
  65    }
  66 
  67    private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf, boolean possibleNext) {
  68       super(dbg.getCDebugger());
  69       this.cfa = cfa;
  70       this.rip = rip;
  71       this.dbg = dbg;
  72       this.dwarf = dwarf;
  73       this.possibleNext = possibleNext;
  74    }
  75 
  76    // override base class impl to avoid ELF parsing
  77    public ClosestSymbol closestSymbolToPC() {
  78       // try native lookup in debugger.
  79       return dbg.lookup(dbg.getAddressValue(pc()));
  80    }
  81 
  82    public Address pc() {
  83       return rip;
  84    }
  85 
  86    public Address localVariableBase() {
  87       return cfa;
  88    }
  89 
  90    private Address getNextPC(boolean useDwarf) {
  91      try {
  92        long offs = useDwarf ? dwarf.getReturnAddressOffsetFromCFA()
  93                             : ADDRESS_SIZE;


 116          if (!dwarf.isBPOffsetAvailable() && // Use RBP as CFA
 117              (nextCFAReg == AMD64ThreadContext.RBP) &&
 118              (nextCFAReg != dwarf.getCFARegister())) {
 119            nextCFA = context.getRegisterAsAddress(AMD64ThreadContext.RBP);
 120            if (nextCFA == null) {
 121              return null;
 122            }
 123            nextCFA = nextCFA.getAddressAt(0);
 124          } else {
 125            nextCFA = cfa.getAddressAt(dwarf.getBasePointerOffsetFromCFA());
 126          }
 127        }
 128        if (nextCFA != null) {
 129          nextCFA = nextCFA.addOffsetTo(-nextDwarf.getBasePointerOffsetFromCFA());
 130        }
 131      }
 132 
 133      return isValidFrame(nextCFA, context) ? nextCFA : null;
 134    }
 135 
 136    @Override
 137    public CFrame sender(ThreadProxy thread) {
 138      if (!possibleNext) {
 139        return null;
 140      }
 141 
 142      ThreadContext context = thread.getContext();
 143 
 144      Address nextPC = getNextPC(dwarf != null);
 145      if (nextPC == null) {
 146        return null;
 147      }
 148 
 149      DwarfParser nextDwarf = null;
 150      boolean unsupportedDwarf = false;
 151      if ((dwarf != null) && dwarf.isIn(nextPC)) {
 152        nextDwarf = dwarf;
 153      } else {
 154        Address libptr = dbg.findLibPtrByAddress(nextPC);
 155        if (libptr != null) {
 156          try {
 157            nextDwarf = new DwarfParser(libptr);
 158          } catch (DebuggerException e) {
 159            // Bail out to Java frame
 160          }
 161        }
 162      }
 163 
 164      if (nextDwarf != null) {
 165        try {
 166          nextDwarf.processDwarf(nextPC);
 167        } catch (DebuggerException e) {
 168          // DWARF processing should succeed when the frame is native
 169          // but it might fail if CIE has language personality routine
 170          // and/or LSDA.
 171          nextDwarf = null;
 172          unsupportedDwarf = true;
 173        }











 174      }
 175 

 176      Address nextCFA = getNextCFA(nextDwarf, context);
 177      LinuxAMD64CFrame nextFrame = new LinuxAMD64CFrame(dbg, nextCFA, nextPC, nextDwarf, !unsupportedDwarf);
 178      return isValidFrame(nextCFA, context) ? nextFrame : null;
 179    }
 180 
 181    // package/class internals only
 182    private static final int ADDRESS_SIZE = 8;
 183    private Address rip;
 184    private Address cfa;
 185    private LinuxDebugger dbg;
 186    private DwarfParser dwarf;
 187    private boolean possibleNext;
 188 }
< prev index next >