proctl_test.go 3.0 KB
Newer Older
D
Derek Parker 已提交
1
package proctl_test
D
Derek Parker 已提交
2 3

import (
4
	"bytes"
5
	"syscall"
D
Derek Parker 已提交
6 7
	"testing"

D
Derek Parker 已提交
8 9 10
	"github.com/derekparker/dbg/_helper"
	"github.com/derekparker/dbg/proctl"
)
11

12 13 14 15 16 17 18 19 20 21
func dataAtAddr(pid int, addr uint64) ([]byte, error) {
	data := make([]byte, 1)
	_, err := syscall.PtracePeekData(pid, uintptr(addr), data)
	if err != nil {
		return nil, err
	}

	return data, nil
}

22
func TestAttachProcess(t *testing.T) {
D
Derek Parker 已提交
23
	helper.WithTestProcess("testprog", t, func(p *proctl.DebuggedProcess) {
24 25 26 27
		if !p.ProcessState.Sys().(syscall.WaitStatus).Stopped() {
			t.Errorf("Process was not stopped correctly")
		}
	})
D
Derek Parker 已提交
28
}
29

30
func TestStep(t *testing.T) {
D
Derek Parker 已提交
31
	helper.WithTestProcess("testprog", t, func(p *proctl.DebuggedProcess) {
D
Derek Parker 已提交
32 33 34 35
		if p.ProcessState.Exited() {
			t.Fatal("Process already exited")
		}

D
Derek Parker 已提交
36
		regs := helper.GetRegisters(p, t)
37
		rip := regs.PC()
38

39 40 41 42
		err := p.Step()
		if err != nil {
			t.Fatal("Step():", err)
		}
43

D
Derek Parker 已提交
44
		regs = helper.GetRegisters(p, t)
45

46 47 48 49 50
		if rip >= regs.PC() {
			t.Errorf("Expected %#v to be greater than %#v", regs.PC(), rip)
		}
	})
}
51

52
func TestContinue(t *testing.T) {
D
Derek Parker 已提交
53
	helper.WithTestProcess("continuetestprog", t, func(p *proctl.DebuggedProcess) {
54 55 56 57 58 59 60 61 62 63 64 65 66
		if p.ProcessState.Exited() {
			t.Fatal("Process already exited")
		}

		err := p.Continue()
		if err != nil {
			t.Fatal("Continue():", err)
		}

		if !p.ProcessState.Success() {
			t.Fatal("Process did not exit successfully")
		}
	})
67
}
68 69

func TestBreakPoint(t *testing.T) {
D
Derek Parker 已提交
70
	helper.WithTestProcess("testprog", t, func(p *proctl.DebuggedProcess) {
71 72 73 74 75 76 77 78 79 80 81 82 83 84
		sleepytimefunc := p.GoSymTable.LookupFunc("main.sleepytime")
		sleepyaddr := sleepytimefunc.Entry

		bp, err := p.Break(uintptr(sleepyaddr))
		if err != nil {
			t.Fatal("Break():", err)
		}

		breakpc := bp.Addr + 1
		err = p.Continue()
		if err != nil {
			t.Fatal("Continue():", err)
		}

D
Derek Parker 已提交
85
		regs := helper.GetRegisters(p, t)
86 87 88 89 90 91 92 93 94 95 96

		pc := regs.PC()
		if pc != breakpc {
			t.Fatalf("Break not respected:\nPC:%d\nFN:%d\n", pc, breakpc)
		}

		err = p.Step()
		if err != nil {
			t.Fatal(err)
		}

D
Derek Parker 已提交
97
		regs = helper.GetRegisters(p, t)
98 99 100 101 102 103

		pc = regs.PC()
		if pc == breakpc {
			t.Fatalf("Step not respected:\nPC:%d\nFN:%d\n", pc, breakpc)
		}
	})
104
}
105 106

func TestBreakPointWithNonExistantFunction(t *testing.T) {
D
Derek Parker 已提交
107
	helper.WithTestProcess("testprog", t, func(p *proctl.DebuggedProcess) {
108 109 110 111 112
		_, err := p.Break(uintptr(0))
		if err == nil {
			t.Fatal("Should not be able to break at non existant function")
		}
	})
113
}
114 115

func TestClearBreakPoint(t *testing.T) {
D
Derek Parker 已提交
116
	helper.WithTestProcess("testprog", t, func(p *proctl.DebuggedProcess) {
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
		fn := p.GoSymTable.LookupFunc("main.sleepytime")
		bp, err := p.Break(uintptr(fn.Entry))
		if err != nil {
			t.Fatal("Break():", err)
		}

		int3, err := dataAtAddr(p.Pid, bp.Addr)
		if err != nil {
			t.Fatal(err)
		}

		bp, err = p.Clear(fn.Entry)
		if err != nil {
			t.Fatal("Break():", err)
		}

		data, err := dataAtAddr(p.Pid, bp.Addr)
		if err != nil {
			t.Fatal(err)
		}

		if bytes.Equal(data, int3) {
			t.Fatalf("Breakpoint was not cleared data: %#v, int3: %#v", data, int3)
		}

		if len(p.BreakPoints) != 0 {
			t.Fatal("Breakpoint not removed internally")
		}
	})
146
}