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  }