< prev index next >

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

Print this page




  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 }


  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         dwarf = new DwarfParser(libptr);
  42         try {
  43           dwarf.processDwarf(rip);
  44         } catch (DebuggerException e) {
  45           // DWARF processing should succeed when the frame is native
  46           // but it might fail if Common Information Entry (CIE) has language
  47           // personality routine and/or Language Specific Data Area (LSDA).
  48           return new LinuxAMD64CFrame(dbg, cfa, rip, dwarf, true);
  49         }
  50         cfa = ((dwarf.getCFARegister() == AMD64ThreadContext.RBP) &&
  51                !dwarf.isBPOffsetAvailable())
  52                   ? context.getRegisterAsAddress(AMD64ThreadContext.RBP)
  53                   : context.getRegisterAsAddress(dwarf.getCFARegister())
  54                            .addOffsetTo(dwarf.getCFAOffset());



  55       }
  56 
  57       return (cfa == null) ? null
  58                            : new LinuxAMD64CFrame(dbg, cfa, rip, dwarf);
  59    }
  60 
  61    private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf) {
  62       this(dbg, cfa, rip, dwarf, false);
  63    }
  64 
  65    private LinuxAMD64CFrame(LinuxDebugger dbg, Address cfa, Address rip, DwarfParser dwarf, boolean lastFrame) {
  66       super(dbg.getCDebugger());
  67       this.cfa = cfa;
  68       this.rip = rip;
  69       this.dbg = dbg;
  70       this.dwarf = dwarf;
  71       this.lastFrame = lastFrame;
  72    }
  73 
  74    // override base class impl to avoid ELF parsing
  75    public ClosestSymbol closestSymbolToPC() {
  76       // try native lookup in debugger.
  77       return dbg.lookup(dbg.getAddressValue(pc()));
  78    }
  79 
  80    public Address pc() {
  81       return rip;
  82    }
  83 
  84    public Address localVariableBase() {
  85       return cfa;
  86    }
  87 
  88    private Address getNextPC(boolean useDwarf) {
  89      try {
  90        long offs = useDwarf ? dwarf.getReturnAddressOffsetFromCFA()
  91                             : ADDRESS_SIZE;


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











 171      }
 172 

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