threads_linux.go 1.6 KB
Newer Older
D
Derek Parker 已提交
1 2 3
package proctl

import (
4
	"errors"
D
Derek Parker 已提交
5 6 7 8 9 10 11
	"fmt"

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

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

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 已提交
22
		return fmt.Errorf("Halt err %s %d", err, t.Id)
D
Derek Parker 已提交
23
	}
D
Derek Parker 已提交
24
	_, _, err = wait(t.Id, 0)
D
Derek Parker 已提交
25
	if err != nil {
D
Derek Parker 已提交
26
		return fmt.Errorf("wait err %s %d", err, t.Id)
D
Derek Parker 已提交
27 28 29 30
	}
	return nil
}

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

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

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

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

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

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

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