diff --git a/proc/stack.go b/proc/stack.go index 39486a794e7c5161a643c00fc62fd5740429a772..ae28b95572af895efadec7101d7f2496c1d055d0 100644 --- a/proc/stack.go +++ b/proc/stack.go @@ -23,7 +23,11 @@ type Stackframe struct { Current Location // Address of the call instruction for the function above on the call stack. Call Location + // Start address of the stack frame. CFA int64 + // Description of the stack frame. + FDE *frame.FrameDescriptionEntry + // Return address for this stack frame (as read from the stack frame itself). Ret uint64 } @@ -179,7 +183,7 @@ func (dbp *Process) frameInfo(pc, sp uint64, top bool) (Stackframe, error) { if err != nil { return Stackframe{}, err } - r := Stackframe{Current: Location{PC: pc, File: f, Line: l, Fn: fn}, CFA: cfa, Ret: binary.LittleEndian.Uint64(data)} + r := Stackframe{Current: Location{PC: pc, File: f, Line: l, Fn: fn}, CFA: cfa, FDE: fde, Ret: binary.LittleEndian.Uint64(data)} if !top { r.Call.File, r.Call.Line, r.Call.Fn = dbp.PCToLine(pc - 1) r.Call.PC, _, _ = dbp.goSymTable.LineToPC(r.Call.File, r.Call.Line) diff --git a/proc/threads.go b/proc/threads.go index 245dbb561a7e65e2ef60acbee5d0c972e302b39e..ee606de91ed995cd3f28b98f83e01903705c9834 100644 --- a/proc/threads.go +++ b/proc/threads.go @@ -11,7 +11,6 @@ import ( "runtime" "github.com/derekparker/delve/dwarf/debug/dwarf" - "github.com/derekparker/delve/dwarf/frame" ) // Thread represents a single thread in the traced process @@ -153,25 +152,17 @@ func (dbp *Process) setNextBreakpoints() (err error) { return err } - // Grab info on our current stack frame. Used to determine - // whether we may be stepping outside of the current function. - fde, err := dbp.frameEntries.FDEForPC(topframe.Current.PC) - if err != nil { - return err - } - if filepath.Ext(topframe.Current.File) != ".go" { - return dbp.cnext(topframe, fde) + return dbp.cnext(topframe) } - return dbp.next(dbp.SelectedGoroutine, topframe, fde) + return dbp.next(dbp.SelectedGoroutine, topframe) } // Set breakpoints at every line, and the return address. Also look for // a deferred function and set a breakpoint there too. -// The first return value is set to true if the goroutine is in the process of exiting -func (dbp *Process) next(g *G, topframe Stackframe, fde *frame.FrameDescriptionEntry) error { - pcs := dbp.lineInfo.AllPCsBetween(fde.Begin(), fde.End()-1, topframe.Current.File) +func (dbp *Process) next(g *G, topframe Stackframe) error { + pcs := dbp.lineInfo.AllPCsBetween(topframe.FDE.Begin(), topframe.FDE.End()-1, topframe.Current.File) var deferpc uint64 = 0 if g != nil && g.DeferPC != 0 { @@ -185,7 +176,7 @@ func (dbp *Process) next(g *G, topframe Stackframe, fde *frame.FrameDescriptionE var covered bool for i := range pcs { - if fde.Cover(pcs[i]) { + if topframe.FDE.Cover(pcs[i]) { covered = true break } @@ -207,8 +198,8 @@ func (dbp *Process) next(g *G, topframe Stackframe, fde *frame.FrameDescriptionE // Set a breakpoint at every reachable location, as well as the return address. Without // the benefit of an AST we can't be sure we're not at a branching statement and thus // cannot accurately predict where we may end up. -func (dbp *Process) cnext(topframe Stackframe, fde *frame.FrameDescriptionEntry) error { - pcs := dbp.lineInfo.AllPCsBetween(fde.Begin(), fde.End(), topframe.Current.File) +func (dbp *Process) cnext(topframe Stackframe) error { + pcs := dbp.lineInfo.AllPCsBetween(topframe.FDE.Begin(), topframe.FDE.End(), topframe.Current.File) pcs = append(pcs, topframe.Ret) return dbp.setTempBreakpoints(topframe.Current.PC, pcs, sameGoroutineCondition(dbp.SelectedGoroutine)) }