Enable next to clean up after itself

This commit is contained in:
Derek Parker
2014-07-21 18:20:16 -05:00
parent dcf21c2d0d
commit cba9ac206d
3 changed files with 45 additions and 24 deletions

View File

@ -85,7 +85,7 @@ func (dbl *DebugLineInfo) NextLocAfterPC(pc uint64) *Location {
for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() { for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() {
findAndExecOpcode(sm, buf, b) findAndExecOpcode(sm, buf, b)
if sm.Line > line { if sm.Line != line {
break break
} }
} }
@ -134,7 +134,7 @@ func (dbl *DebugLineInfo) LoopExitLocation(pc uint64) *Location {
for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() { for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() {
findAndExecOpcode(sm, buf, b) findAndExecOpcode(sm, buf, b)
if sm.Line > line { if sm.Line != line {
break break
} }
} }
@ -148,7 +148,7 @@ func executeUntilPC(sm *StateMachine, buf *bytes.Buffer, pc uint64) {
for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() { for b, err := buf.ReadByte(); err == nil; b, err = buf.ReadByte() {
findAndExecOpcode(sm, buf, b) findAndExecOpcode(sm, buf, b)
if line != 0 && sm.Line > line { if line != 0 && sm.Line != line {
break break
} }

View File

@ -18,16 +18,17 @@ import (
// Struct representing a debugged process. Holds onto pid, register values, // Struct representing a debugged process. Holds onto pid, register values,
// process struct and process state. // process struct and process state.
type DebuggedProcess struct { type DebuggedProcess struct {
Pid int Pid int
Regs *syscall.PtraceRegs Regs *syscall.PtraceRegs
Process *os.Process Process *os.Process
ProcessState *os.ProcessState ProcessState *os.ProcessState
Executable *elf.File Executable *elf.File
Symbols []elf.Symbol Symbols []elf.Symbol
GoSymTable *gosym.Table GoSymTable *gosym.Table
FrameEntries frame.FrameDescriptionEntries FrameEntries frame.FrameDescriptionEntries
DebugLine *line.DebugLineInfo DebugLine *line.DebugLineInfo
BreakPoints map[string]*BreakPoint BreakPoints map[string]*BreakPoint
TempBreakPoints map[uint64]*BreakPoint
} }
// Represents a single breakpoint. Stores information on the break // Represents a single breakpoint. Stores information on the break
@ -69,11 +70,12 @@ func NewDebugProcess(pid int) (*DebuggedProcess, error) {
} }
debuggedProc := DebuggedProcess{ debuggedProc := DebuggedProcess{
Pid: pid, Pid: pid,
Regs: &syscall.PtraceRegs{}, Regs: &syscall.PtraceRegs{},
Process: proc, Process: proc,
ProcessState: ps, ProcessState: ps,
BreakPoints: make(map[string]*BreakPoint), BreakPoints: make(map[string]*BreakPoint),
TempBreakPoints: make(map[uint64]*BreakPoint),
} }
err = debuggedProc.LoadInformation() err = debuggedProc.LoadInformation()
@ -228,29 +230,46 @@ func (dbp *DebuggedProcess) Next() error {
} }
loc := dbp.DebugLine.NextLocAfterPC(pc) loc := dbp.DebugLine.NextLocAfterPC(pc)
addrs = append(addrs, loc.Address)
if !fde.AddressRange.Cover(loc.Address) { if !fde.AddressRange.Cover(loc.Address) {
// Next line is outside current frame, use return addr. // Next line is outside current frame, use return addr.
addr := dbp.ReturnAddressFromOffset(fde.ReturnAddressOffset(pc)) addr := dbp.ReturnAddressFromOffset(fde.ReturnAddressOffset(pc))
loc = dbp.DebugLine.LocationInfoForPC(addr) loc = dbp.DebugLine.LocationInfoForPC(addr)
addrs = append(addrs, loc.Address)
} }
addrs = append(addrs, loc.Address)
if loc.Delta < 0 { if loc.Delta < 0 {
// We are likely in a loop, set breakpoints at entry and exit. // We are likely in a loop, set breakpoints at entry and exit.
entry := dbp.DebugLine.LoopEntryLocation(loc.Line) entry := dbp.DebugLine.LoopEntryLocation(loc.Line)
exit := dbp.DebugLine.LoopExitLocation(pc) exit := dbp.DebugLine.LoopExitLocation(loc.Address)
addrs = append(addrs, entry.Address, exit.Address) addrs = append(addrs, entry.Address, exit.Address)
} }
for _, addr := range addrs { for _, addr := range addrs {
if _, err := dbp.Break(uintptr(addr)); err != nil { bp, err := dbp.Break(uintptr(addr))
if err != nil {
if _, ok := err.(BreakPointExistsError); !ok { if _, ok := err.(BreakPointExistsError); !ok {
return err return err
} }
continue
}
dbp.TempBreakPoints[addr] = bp
}
err = dbp.Continue()
if err != nil {
return err
}
if bp, ok := dbp.TempBreakPoints[pc]; ok {
_, err := dbp.Clear(bp.Addr)
if err != nil {
return err
} }
} }
return dbp.Continue() return nil
} }
// Continue process until next breakpoint. // Continue process until next breakpoint.

View File

@ -180,9 +180,11 @@ func TestNext(t *testing.T) {
{17, 19}, {17, 19},
{19, 20}, {19, 20},
{20, 22}, {20, 22},
{22, 20}, {22, 19},
{19, 20},
{20, 22}, {20, 22},
{22, 25}, {22, 19},
{19, 25},
{25, 26}, {25, 26},
{26, 30}, {26, 30},
{30, 31}, {30, 31},