Improve Next implementation

Fix bug involving detecting whether or not we have stepped into another
function when we plan on return from the function we are currently in.
This commit is contained in:
Derek Parker 2014-10-13 19:04:38 -05:00
parent 05239b7beb
commit 58c1f54578
4 changed files with 21 additions and 20 deletions

@ -37,7 +37,7 @@ func testnext() {
func main() {
runtime.LockOSThread()
for {
helloworld()
testnext()
fmt.Println("foo")
}
}

@ -56,7 +56,7 @@ func TestFindReturnAddress(t *testing.T) {
syscall.PtracePeekText(p.Pid, uintptr(addr), data)
addr = binary.LittleEndian.Uint64(data)
expected := uint64(0x400ed4)
expected := uint64(0x400ed3)
if addr != expected {
t.Fatalf("return address not found correctly, expected %#v got %#v", expected, addr)
}

@ -254,27 +254,28 @@ func (dbp *DebuggedProcess) Next() error {
loc := dbp.DebugLine.NextLocation(pc, f, l)
if !fde.Cover(loc.Address) {
// Step once to ensure we're not going to step
// into another function before returning.
pc, err = step()
if err != nil {
return err
ret := dbp.ReturnAddressFromOffset(fde.ReturnAddressOffset(pc))
// Attempt to step out of function.
for fde.Cover(pc) {
pc, err = step()
if err != nil {
return err
}
}
if fde.Cover(pc) {
// Unconditionally step out of current function
// Don't bother looking up ret addr, next line is
// outside of current fn, should only be a few
// instructions left to RET
for fde.Cover(pc) {
pc, err = step()
if err != nil {
return err
}
}
if pc == ret {
return nil
}
// We have stepped into another function, return from it
// and continue single stepping through until we
// reach our real destination.
err = dbp.continueToReturnAddress(pc, fde)
if err != nil {
return err
}
}
for {

@ -177,9 +177,9 @@ func TestNext(t *testing.T) {
{26, 27},
{27, 34},
{34, 35},
{35, 40},
{40, 41},
{35, 41},
{41, 40},
{40, 41},
}
fp, err := filepath.Abs("../_fixtures/testnextprog.go")