threads_linux.go 1.6 KB
Newer Older
D
Derek Parker 已提交
1 2 3 4 5 6 7 8 9 10
package proctl

import (
	"fmt"

	sys "golang.org/x/sys/unix"
)

// Not actually used, but necessary
// to be defined.
D
Derek Parker 已提交
11 12 13
type OSSpecificDetails struct {
	registers sys.PtraceRegs
}
D
Derek Parker 已提交
14 15 16 17 18 19 20

func (t *ThreadContext) Halt() error {
	if stopped(t.Id) {
		return nil
	}
	err := sys.Tgkill(t.Process.Pid, t.Id, sys.SIGSTOP)
	if err != nil {
D
Derek Parker 已提交
21
		return fmt.Errorf("Halt err %s %d", err, t.Id)
D
Derek Parker 已提交
22
	}
D
Derek Parker 已提交
23
	_, _, err = wait(t.Id, 0)
D
Derek Parker 已提交
24
	if err != nil {
D
Derek Parker 已提交
25
		return fmt.Errorf("wait err %s %d", err, t.Id)
D
Derek Parker 已提交
26 27 28 29
	}
	return nil
}

D
Cleanup  
Derek Parker 已提交
30
func (t *ThreadContext) resume() error {
D
Derek Parker 已提交
31
	return PtraceCont(t.Id, 0)
D
Derek Parker 已提交
32 33 34 35
}

func (t *ThreadContext) singleStep() error {
	err := sys.PtraceSingleStep(t.Id)
D
Derek Parker 已提交
36
	if err != nil {
D
Derek Parker 已提交
37 38
		return err
	}
D
Derek Parker 已提交
39
	_, _, err = wait(t.Id, 0)
D
Derek Parker 已提交
40 41 42
	return err
}

D
Derek Parker 已提交
43 44
func (t *ThreadContext) blocked() bool {
	// TODO(dp) cache the func pc to remove this lookup
D
Derek Parker 已提交
45
	pc, _ := t.PC()
46
	fn := t.Process.goSymTable.PCToFunc(pc)
D
Derek Parker 已提交
47
	if fn != nil && ((fn.Name == "runtime.futex") || (fn.Name == "runtime.usleep") || (fn.Name == "runtime.clone")) {
D
Derek Parker 已提交
48 49 50 51 52
		return true
	}
	return false
}

53 54
func (thread *ThreadContext) saveRegisters() (Registers, error) {
	if err := sys.PtraceGetRegs(thread.Id, &thread.os.registers); err != nil {
D
Derek Parker 已提交
55
		return nil, fmt.Errorf("could not save register contents")
56 57
	}
	return &Regs{&thread.os.registers}, nil
D
Derek Parker 已提交
58 59
}

60 61
func (thread *ThreadContext) restoreRegisters() error {
	return sys.PtraceSetRegs(thread.Id, &thread.os.registers)
D
Derek Parker 已提交
62
}
D
Derek Parker 已提交
63

64 65
func writeMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error) {
	return sys.PtracePokeData(thread.Id, addr, data)
D
Derek Parker 已提交
66 67
}

68 69
func readMemory(thread *ThreadContext, addr uintptr, data []byte) (int, error) {
	return sys.PtracePeekData(thread.Id, addr, data)
D
Derek Parker 已提交
70
}