github.com/cnboonhan/delve@v0.0.0-20230908061759-363f2388c2fb/pkg/proc/native/ptrace_freebsd.go (about) 1 package native 2 3 // #cgo LDFLAGS: -lutil 4 //#include <sys/types.h> 5 //#include <sys/ptrace.h> 6 // 7 // #include <stdlib.h> 8 // 9 import "C" 10 11 import ( 12 "runtime" 13 "syscall" 14 "unsafe" 15 16 sys "golang.org/x/sys/unix" 17 ) 18 19 // ptraceAttach executes the sys.PtraceAttach call. 20 // pid must be a PID, not a LWPID 21 func ptraceAttach(pid int) error { 22 return sys.PtraceAttach(pid) 23 } 24 25 // ptraceDetach calls ptrace(PTRACE_DETACH). 26 func ptraceDetach(pid int) error { 27 return sys.PtraceDetach(pid) 28 } 29 30 // ptraceCont executes ptrace PTRACE_CONT 31 // id may be a PID or an LWPID 32 func ptraceCont(id, sig int) error { 33 return sys.PtraceCont(id, sig) 34 } 35 36 // ptraceSingleStep executes ptrace PTRACE_SINGLE_STEP. 37 // id may be a PID or an LWPID 38 func ptraceSingleStep(id int) error { 39 return sys.PtraceSingleStep(id) 40 } 41 42 // Get a list of the thread ids of a process 43 func ptraceGetLwpList(pid int) (tids []int32) { 44 numLWPS := C.ptrace(C.PT_GETNUMLWPS, C.pid_t(pid), C.caddr_t(unsafe.Pointer(uintptr(0))), C.int(0)) 45 if numLWPS < 0 { 46 panic("PT_GETNUMLWPS failed") 47 } 48 tids = make([]int32, numLWPS) 49 n := C.ptrace(C.PT_GETLWPLIST, C.pid_t(pid), C.caddr_t(unsafe.Pointer(&tids[0])), C.int(numLWPS)) 50 if n < 0 { 51 panic("PT_GETLWPLIST failed") 52 } 53 return tids[0:n] 54 } 55 56 // Get info of the thread that caused wpid's process to stop. 57 func ptraceGetLwpInfo(wpid int) (info sys.PtraceLwpInfoStruct, err error) { 58 err = sys.PtraceLwpInfo(wpid, &info) 59 return info, err 60 } 61 62 // id may be a PID or an LWPID 63 func ptraceReadData(id int, addr uintptr, data []byte) (n int, err error) { 64 defer runtime.KeepAlive(&data[0]) // PIN 65 return sys.PtraceIO(sys.PIOD_READ_D, id, addr, data, len(data)) 66 } 67 68 // id may be a PID or an LWPID 69 func ptraceWriteData(id int, addr uintptr, data []byte) (n int, err error) { 70 defer runtime.KeepAlive(&data[0]) // PIN 71 return sys.PtraceIO(sys.PIOD_WRITE_D, id, addr, data, len(data)) 72 } 73 74 func ptraceSuspend(id int) error { 75 _, _, e1 := sys.Syscall6(sys.SYS_PTRACE, uintptr(C.PT_SUSPEND), uintptr(id), uintptr(1), uintptr(0), 0, 0) 76 if e1 != 0 { 77 return syscall.Errno(e1) 78 } 79 return nil 80 } 81 82 func ptraceResume(id int) error { 83 _, _, e1 := sys.Syscall6(sys.SYS_PTRACE, uintptr(C.PT_RESUME), uintptr(id), uintptr(1), uintptr(0), 0, 0) 84 if e1 != 0 { 85 return syscall.Errno(e1) 86 } 87 return nil 88 } 89 90 func ptraceSetStep(id int) error { 91 _, _, e1 := sys.Syscall6(sys.SYS_PTRACE, uintptr(C.PT_SETSTEP), uintptr(id), uintptr(0), uintptr(0), 0, 0) 92 if e1 != 0 { 93 return syscall.Errno(e1) 94 } 95 return nil 96 } 97 98 func ptraceClearStep(id int) error { 99 _, _, e1 := sys.Syscall6(sys.SYS_PTRACE, uintptr(C.PT_CLEARSTEP), uintptr(id), uintptr(0), uintptr(0), 0, 0) 100 if e1 != 0 { 101 return syscall.Errno(e1) 102 } 103 return nil 104 }