aboutsummaryrefslogtreecommitdiff
path: root/lib/libsys/ptrace.2
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsys/ptrace.2')
-rw-r--r--lib/libsys/ptrace.21451
1 files changed, 1451 insertions, 0 deletions
diff --git a/lib/libsys/ptrace.2 b/lib/libsys/ptrace.2
new file mode 100644
index 000000000000..7aa24a3f820b
--- /dev/null
+++ b/lib/libsys/ptrace.2
@@ -0,0 +1,1451 @@
+.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
+.\"
+.\" This file is in the public domain.
+.Dd June 19, 2025
+.Dt PTRACE 2
+.Os
+.Sh NAME
+.Nm ptrace
+.Nd process tracing and debugging
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/ptrace.h
+.Ft int
+.Fn ptrace "int request" "pid_t pid" "caddr_t addr" "int data"
+.Sh DESCRIPTION
+The
+.Fn ptrace
+system call
+provides tracing and debugging facilities.
+It allows one process
+(the
+.Em tracing
+process)
+to control another
+(the
+.Em traced
+process).
+The tracing process must first attach to the traced process, and then
+issue a series of
+.Fn ptrace
+system calls to control the execution of the process, as well as access
+process memory and register state.
+For the duration of the tracing session, the traced process will be
+.Dq re-parented ,
+with its parent process ID (and resulting behavior)
+changed to the tracing process.
+It is permissible for a tracing process to attach to more than one
+other process at a time.
+When the tracing process has completed its work, it must detach the
+traced process; if a tracing process exits without first detaching all
+processes it has attached, those processes will be killed.
+.Pp
+Most of the time, the traced process runs normally, but when it
+receives a signal
+(see
+.Xr sigaction 2 ) ,
+it stops.
+The tracing process is expected to notice this via
+.Xr wait 2
+or the delivery of a
+.Dv SIGCHLD
+signal, examine the state of the stopped process, and cause it to
+terminate or continue as appropriate.
+The signal may be a normal process signal, generated as a result of
+traced process behavior, or use of the
+.Xr kill 2
+system call; alternatively, it may be generated by the tracing facility
+as a result of attaching, stepping by the tracing
+process,
+or an event in the traced process.
+The tracing process may choose to intercept the signal, using it to
+observe process behavior (such as
+.Dv SIGTRAP ) ,
+or forward the signal to the process if appropriate.
+The
+.Fn ptrace
+system call
+is the mechanism by which all this happens.
+.Pp
+A traced process may report additional signal stops corresponding to
+events in the traced process.
+These additional signal stops are reported as
+.Dv SIGTRAP
+or
+.Dv SIGSTOP
+signals.
+The tracing process can use the
+.Dv PT_LWPINFO
+request to determine which events are associated with a
+.Dv SIGTRAP
+or
+.Dv SIGSTOP
+signal.
+Note that multiple events may be associated with a single signal.
+For example, events indicated by the
+.Dv PL_FLAG_BORN ,
+.Dv PL_FLAG_FORKED ,
+and
+.Dv PL_FLAG_EXEC
+flags are also reported as a system call exit event
+.Pq Dv PL_FLAG_SCX .
+The signal stop for a new child process enabled via
+.Dv PTRACE_FORK
+will report a
+.Dv SIGSTOP
+signal.
+All other additional signal stops use
+.Dv SIGTRAP .
+.Sh DETACH AND TERMINATION
+.Pp
+Normally, exiting tracing process should wait for all pending
+debugging events and then detach from all alive traced processes
+before exiting using
+.Dv PT_DETACH
+request.
+If tracing process exits without detaching, for instance due to abnormal
+termination, the destiny of the traced children processes is determined
+by the
+.Dv kern.kill_on_debugger_exit
+sysctl control.
+.Pp
+If the control is set to the default value 1, such traced processes
+are terminated.
+If set to zero, kernel implicitly detaches traced processes.
+Traced processes are un-stopped if needed, and then continue the execution
+without tracing.
+Kernel drops any
+.Dv SIGTRAP
+signals queued to the traced children, which could be either generated by
+not yet consumed debug events, or sent by other means, the later should
+not be done anyway.
+.Sh SELECTING THE TARGET
+The
+.Fa pid
+argument of the call specifies the target on which to perform
+the requested operation.
+For operations affecting the global process state, the process ID
+is typically passed there.
+Similarly, for operations affecting only a thread, the thread ID
+needs to be passed.
+.Pp
+Still, for global operations, the ID of any thread can be used as the
+target, and system will perform the request on the process owning
+that thread.
+If a thread operation got the process ID as
+.Fa pid ,
+the system randomly selects a thread from among the threads owned
+by the process.
+For single-threaded processes there is no difference between specifying
+process or thread ID as the target.
+.Sh DISABLING PTRACE
+The
+.Nm
+subsystem provides rich facilities to manipulate other processes state.
+Sometimes it may be desirable to disallow it either completely, or limit
+its scope.
+The following controls are provided for this:
+.Bl -tag -width security.bsd.unprivileged_proc_debug
+.It Dv security.bsd.allow_ptrace
+Setting this sysctl to zero makes
+.Nm
+return
+.Er ENOSYS
+always as if the syscall is not implemented by the kernel.
+.It Dv security.bsd.unprivileged_proc_debug
+Setting this sysctl to zero disallows the use of
+.Fn ptrace
+by unprivileged processes.
+.It Dv security.bsd.see_other_uids
+Setting this sysctl to zero prevents
+.Fn ptrace
+requests from targeting processes with a real user identifier different
+from the caller's.
+These requests will fail with error
+.Er ESRCH .
+.It Dv security.bsd.see_other_gids
+Setting this sysctl to zero disallows
+.Fn ptrace
+requests from processes that have no groups in common with the target process,
+considering their sets of real and supplementary groups.
+These requests will fail with error
+.Er ESRCH .
+.It Dv security.bsd.see_jail_proc
+Setting this sysctl to zero disallows
+.Fn ptrace
+requests from processes belonging to a different jail than that of the target
+process, even if the requesting process' jail is an ancestor of the target
+process'.
+These requests will fail with error
+.Er ESRCH .
+.It Dv securelevel and init
+The
+.Xr init 1
+process can only be traced with
+.Nm
+if securelevel is zero.
+.It Dv procctl(2) PROC_TRACE_CTL
+Process can deny attempts to trace itself with
+.Xr procctl 2
+.Dv PROC_TRACE_CTL
+request.
+In this case requests return
+.Xr EPERM
+error.
+.El
+.Sh TRACING EVENTS
+.Pp
+Each traced process has a tracing event mask.
+An event in the traced process only reports a
+signal stop if the corresponding flag is set in the tracing event mask.
+The current set of tracing event flags include:
+.Bl -tag -width "Dv PTRACE_SYSCALL"
+.It Dv PTRACE_EXEC
+Report a stop for a successful invocation of
+.Xr execve 2 .
+This event is indicated by the
+.Dv PL_FLAG_EXEC
+flag in the
+.Va pl_flags
+member of
+.Vt "struct ptrace_lwpinfo" .
+.It Dv PTRACE_SCE
+Report a stop on each system call entry.
+This event is indicated by the
+.Dv PL_FLAG_SCE
+flag in the
+.Va pl_flags
+member of
+.Vt "struct ptrace_lwpinfo" .
+.It Dv PTRACE_SCX
+Report a stop on each system call exit.
+This event is indicated by the
+.Dv PL_FLAG_SCX
+flag in the
+.Va pl_flags
+member of
+.Vt "struct ptrace_lwpinfo" .
+.It Dv PTRACE_SYSCALL
+Report stops for both system call entry and exit.
+.It Dv PTRACE_FORK
+This event flag controls tracing for new child processes of a traced process.
+.Pp
+When this event flag is enabled,
+new child processes will enable tracing and stop before executing their
+first instruction.
+The new child process will include the
+.Dv PL_FLAG_CHILD
+flag in the
+.Va pl_flags
+member of
+.Vt "struct ptrace_lwpinfo" .
+The traced process will report a stop that includes the
+.Dv PL_FLAG_FORKED
+flag.
+The process ID of the new child process will also be present in the
+.Va pl_child_pid
+member of
+.Vt "struct ptrace_lwpinfo" .
+If the new child process was created via
+.Xr vfork 2 ,
+the traced process's stop will also include the
+.Dv PL_FLAG_VFORKED
+flag.
+Note that new child processes will be attached with the default
+tracing event mask;
+they do not inherit the event mask of the traced process.
+.Pp
+When this event flag is not enabled,
+new child processes will execute without tracing enabled.
+.It Dv PTRACE_LWP
+This event flag controls tracing of LWP
+.Pq kernel thread
+creation and destruction.
+When this event is enabled,
+new LWPs will stop and report an event with
+.Dv PL_FLAG_BORN
+set before executing their first instruction,
+and exiting LWPs will stop and report an event with
+.Dv PL_FLAG_EXITED
+set before completing their termination.
+.Pp
+Note that new processes do not report an event for the creation of their
+initial thread,
+and exiting processes do not report an event for the termination of the
+last thread.
+.It Dv PTRACE_VFORK
+Report a stop event when a parent process resumes after a
+.Xr vfork 2 .
+.Pp
+When a thread in the traced process creates a new child process via
+.Xr vfork 2 ,
+the stop that reports
+.Dv PL_FLAG_FORKED
+and
+.Dv PL_FLAG_SCX
+occurs just after the child process is created,
+but before the thread waits for the child process to stop sharing process
+memory.
+If a debugger is not tracing the new child process,
+it must ensure that no breakpoints are enabled in the shared process
+memory before detaching from the new child process.
+This means that no breakpoints are enabled in the parent process either.
+.Pp
+The
+.Dv PTRACE_VFORK
+flag enables a new stop that indicates when the new child process stops
+sharing the process memory of the parent process.
+A debugger can reinsert breakpoints in the parent process and resume it
+in response to this event.
+This event is indicated by setting the
+.Dv PL_FLAG_VFORK_DONE
+flag.
+.El
+.Pp
+The default tracing event mask when attaching to a process via
+.Dv PT_ATTACH ,
+.Dv PT_TRACE_ME ,
+or
+.Dv PTRACE_FORK
+includes only
+.Dv PTRACE_EXEC
+events.
+All other event flags are disabled.
+.Sh PTRACE REQUESTS
+.Pp
+The
+.Fa request
+argument specifies what operation is being performed; the meaning of
+the rest of the arguments depends on the operation, but except for one
+special case noted below, all
+.Fn ptrace
+calls are made by the tracing process, and the
+.Fa pid
+argument specifies the process ID of the traced process
+or a corresponding thread ID.
+The
+.Fa request
+argument
+can be:
+.Bl -tag -width "Dv PT_GET_EVENT_MASK"
+.It Dv PT_TRACE_ME
+This request is the only one used by the traced process; it declares
+that the process expects to be traced by its parent.
+All the other arguments are ignored.
+(If the parent process does not expect to trace the child, it will
+probably be rather confused by the results; once the traced process
+stops, it cannot be made to continue except via
+.Fn ptrace . )
+When a process has used this request and calls
+.Xr execve 2
+or any of the routines built on it
+(such as
+.Xr execv 3 ) ,
+it will stop before executing the first instruction of the new image.
+Also, any setuid or setgid bits on the executable being executed will
+be ignored.
+If the child was created by
+.Xr vfork 2
+system call or
+.Xr rfork 2
+call with the
+.Dv RFMEM
+flag specified, the debugging events are reported to the parent
+only after the
+.Xr execve 2
+is executed.
+.It Dv PT_READ_I , Dv PT_READ_D
+These requests read a single
+.Vt int
+of data from the traced process's address space.
+Traditionally,
+.Fn ptrace
+has allowed for machines with distinct address spaces for instruction
+and data, which is why there are two requests: conceptually,
+.Dv PT_READ_I
+reads from the instruction space and
+.Dv PT_READ_D
+reads from the data space.
+In the current
+.Fx
+implementation, these two requests are completely identical.
+The
+.Fa addr
+argument specifies the address
+(in the traced process's virtual address space)
+at which the read is to be done.
+This address does not have to meet any alignment constraints.
+The value read is returned as the return value from
+.Fn ptrace .
+.It Dv PT_WRITE_I , Dv PT_WRITE_D
+These requests parallel
+.Dv PT_READ_I
+and
+.Dv PT_READ_D ,
+except that they write rather than read.
+The
+.Fa data
+argument supplies the value to be written.
+.It Dv PT_IO
+This request allows reading and writing arbitrary amounts of data in
+the traced process's address space.
+The
+.Fa addr
+argument specifies a pointer to a
+.Vt "struct ptrace_io_desc" ,
+which is defined as follows:
+.Bd -literal
+struct ptrace_io_desc {
+ int piod_op; /* I/O operation */
+ void *piod_offs; /* child offset */
+ void *piod_addr; /* parent offset */
+ size_t piod_len; /* request length */
+};
+
+/*
+ * Operations in piod_op.
+ */
+#define PIOD_READ_D 1 /* Read from D space */
+#define PIOD_WRITE_D 2 /* Write to D space */
+#define PIOD_READ_I 3 /* Read from I space */
+#define PIOD_WRITE_I 4 /* Write to I space */
+.Ed
+.Pp
+The
+.Fa data
+argument is ignored.
+The actual number of bytes read or written is stored in
+.Va piod_len
+upon return.
+.It Dv PT_CONTINUE
+The traced process continues execution.
+The
+.Fa addr
+argument
+is an address specifying the place where execution is to be resumed
+(a new value for the program counter),
+or
+.Po Vt caddr_t Pc Ns 1
+to indicate that execution is to pick up where it left off.
+The
+.Fa data
+argument
+provides a signal number to be delivered to the traced process as it
+resumes execution, or 0 if no signal is to be sent.
+.It Dv PT_STEP
+The traced process is single stepped one instruction.
+The
+.Fa addr
+argument
+should be passed
+.Po Vt caddr_t Pc Ns 1 .
+The
+.Fa data
+argument
+provides a signal number to be delivered to the traced process as it
+resumes execution, or 0 if no signal is to be sent.
+.It Dv PT_KILL
+The traced process terminates, as if
+.Dv PT_CONTINUE
+had been used with
+.Dv SIGKILL
+given as the signal to be delivered.
+.It Dv PT_ATTACH
+This request allows a process to gain control of an otherwise
+unrelated process and begin tracing it.
+It does not need any cooperation from the process to trace.
+In
+this case,
+.Fa pid
+specifies the process ID of the process to trace, and the other
+two arguments are ignored.
+This request requires that the target process must have the same real
+UID as the tracing process, and that it must not be executing a setuid
+or setgid executable.
+(If the tracing process is running as root, these restrictions do not
+apply.)
+The tracing process will see the newly-traced process stop and may
+then control it as if it had been traced all along.
+.It Dv PT_DETACH
+This request is like PT_CONTINUE, except that it does not allow
+specifying an alternate place to continue execution, and after it
+succeeds, the traced process is no longer traced and continues
+execution normally.
+.Pp
+The parent of the traced process will be sent a
+.Dv SIGCHLD
+to indicate that the process has continued from a stopped state regardless of
+whether the process was in a stopped state prior to the corresponding
+.Dv PT_ATTACH
+request.
+A
+.Xr wait 2
+for the traced process would indicate that it had been continued.
+.It Dv PT_GETREGS
+This request reads the traced process's machine registers into the
+.Do
+.Vt "struct reg"
+.Dc
+(defined in
+.In machine/reg.h )
+pointed to by
+.Fa addr .
+.It Dv PT_SETREGS
+This request is the converse of
+.Dv PT_GETREGS ;
+it loads the traced process's machine registers from the
+.Do
+.Vt "struct reg"
+.Dc
+(defined in
+.In machine/reg.h )
+pointed to by
+.Fa addr .
+.It Dv PT_GETFPREGS
+This request reads the traced process's floating-point registers into
+the
+.Do
+.Vt "struct fpreg"
+.Dc
+(defined in
+.In machine/reg.h )
+pointed to by
+.Fa addr .
+.It Dv PT_SETFPREGS
+This request is the converse of
+.Dv PT_GETFPREGS ;
+it loads the traced process's floating-point registers from the
+.Do
+.Vt "struct fpreg"
+.Dc
+(defined in
+.In machine/reg.h )
+pointed to by
+.Fa addr .
+.It Dv PT_GETDBREGS
+This request reads the traced process's debug registers into
+the
+.Do
+.Vt "struct dbreg"
+.Dc
+(defined in
+.In machine/reg.h )
+pointed to by
+.Fa addr .
+.It Dv PT_SETDBREGS
+This request is the converse of
+.Dv PT_GETDBREGS ;
+it loads the traced process's debug registers from the
+.Do
+.Vt "struct dbreg"
+.Dc
+(defined in
+.In machine/reg.h )
+pointed to by
+.Fa addr .
+.It Dv PT_GETREGSET
+This request reads the registers from the traced process.
+The
+.Fa data
+argument specifies the register set to read, with the
+.Fa addr
+argument pointing at a
+.Vt "struct iovec"
+where the
+.Va iov_base
+field points to a register set specific structure to hold the registers,
+and the
+.Va iov_len
+field holds the length of the structure.
+.It Dv PT_SETREGSET
+This request writes to the registers of the traced process.
+The
+.Fa data
+argument specifies the register set to write to, with the
+.Fa addr
+argument pointing at a
+.Vt "struct iovec"
+where the
+.Va iov_base
+field points to a register set specific structure to hold the registers,
+and the
+.Va iov_len
+field holds the length of the structure.
+If
+.Va iov_base
+is NULL the kernel will return the expected length of the register set
+specific structure in the
+.Va iov_len
+field and not change the target register set.
+.It Dv PT_LWPINFO
+This request can be used to obtain information about the kernel thread,
+also known as light-weight process, that caused the traced process to stop.
+The
+.Fa addr
+argument specifies a pointer to a
+.Vt "struct ptrace_lwpinfo" ,
+which is defined as follows:
+.Bd -literal
+struct ptrace_lwpinfo {
+ lwpid_t pl_lwpid;
+ int pl_event;
+ int pl_flags;
+ sigset_t pl_sigmask;
+ sigset_t pl_siglist;
+ siginfo_t pl_siginfo;
+ char pl_tdname[MAXCOMLEN + 1];
+ pid_t pl_child_pid;
+ u_int pl_syscall_code;
+ u_int pl_syscall_narg;
+};
+.Ed
+.Pp
+The
+.Fa data
+argument is to be set to the size of the structure known to the caller.
+This allows the structure to grow without affecting older programs.
+.Pp
+The fields in the
+.Vt "struct ptrace_lwpinfo"
+have the following meaning:
+.Bl -tag -width indent -compact
+.It Va pl_lwpid
+LWP id of the thread
+.It Va pl_event
+Event that caused the stop.
+Currently defined events are:
+.Bl -tag -width "Dv PL_EVENT_SIGNAL" -compact
+.It Dv PL_EVENT_NONE
+No reason given
+.It Dv PL_EVENT_SIGNAL
+Thread stopped due to the pending signal
+.El
+.It Va pl_flags
+Flags that specify additional details about observed stop.
+Currently defined flags are:
+.Bl -tag -width indent -compact
+.It Dv PL_FLAG_SCE
+The thread stopped due to system call entry, right after the kernel is entered.
+The debugger may examine syscall arguments that are stored in memory and
+registers according to the ABI of the current process, and modify them,
+if needed.
+.It Dv PL_FLAG_SCX
+The thread is stopped immediately before syscall is returning to the usermode.
+The debugger may examine system call return values in the ABI-defined registers
+and/or memory.
+.It Dv PL_FLAG_EXEC
+When
+.Dv PL_FLAG_SCX
+is set, this flag may be additionally specified to inform that the
+program being executed by debuggee process has been changed by successful
+execution of a system call from the
+.Fn execve 2
+family.
+.It Dv PL_FLAG_SI
+Indicates that
+.Va pl_siginfo
+member of
+.Vt "struct ptrace_lwpinfo"
+contains valid information.
+.It Dv PL_FLAG_FORKED
+Indicates that the process is returning from a call to
+.Fn fork 2
+that created a new child process.
+The process identifier of the new process is available in the
+.Va pl_child_pid
+member of
+.Vt "struct ptrace_lwpinfo" .
+.It Dv PL_FLAG_CHILD
+The flag is set for first event reported from a new child which is
+automatically attached when
+.Dv PTRACE_FORK
+is enabled.
+.It Dv PL_FLAG_BORN
+This flag is set for the first event reported from a new LWP when
+.Dv PTRACE_LWP
+is enabled.
+It is reported along with
+.Dv PL_FLAG_SCX .
+.It Dv PL_FLAG_EXITED
+This flag is set for the last event reported by an exiting LWP when
+.Dv PTRACE_LWP
+is enabled.
+Note that this event is not reported when the last LWP in a process exits.
+The termination of the last thread is reported via a normal process exit
+event.
+.It Dv PL_FLAG_VFORKED
+Indicates that the thread is returning from a call to
+.Xr vfork 2
+that created a new child process.
+This flag is set in addition to
+.Dv PL_FLAG_FORKED .
+.It Dv PL_FLAG_VFORK_DONE
+Indicates that the thread has resumed after a child process created via
+.Xr vfork 2
+has stopped sharing its address space with the traced process.
+.El
+.It Va pl_sigmask
+The current signal mask of the LWP
+.It Va pl_siglist
+The current pending set of signals for the LWP.
+Note that signals that are delivered to the process would not appear
+on an LWP siglist until the thread is selected for delivery.
+.It Va pl_siginfo
+The siginfo that accompanies the signal pending.
+Only valid for
+.Dv PL_EVENT_SIGNAL
+stop when
+.Dv PL_FLAG_SI
+is set in
+.Va pl_flags .
+.It Va pl_tdname
+The name of the thread.
+.It Va pl_child_pid
+The process identifier of the new child process.
+Only valid for a
+.Dv PL_EVENT_SIGNAL
+stop when
+.Dv PL_FLAG_FORKED
+is set in
+.Va pl_flags .
+.It Va pl_syscall_code
+The ABI-specific identifier of the current system call.
+Note that for indirect system calls this field reports the indirected
+system call.
+Only valid when
+.Dv PL_FLAG_SCE
+or
+.Dv PL_FLAG_SCX
+is set in
+.Va pl_flags .
+.It Va pl_syscall_narg
+The number of arguments passed to the current system call not counting
+the system call identifier.
+Note that for indirect system calls this field reports the arguments
+passed to the indirected system call.
+Only valid when
+.Dv PL_FLAG_SCE
+or
+.Dv PL_FLAG_SCX
+is set in
+.Va pl_flags .
+.El
+.It Dv PT_GETNUMLWPS
+This request returns the number of kernel threads associated with the
+traced process.
+.It Dv PT_GETLWPLIST
+This request can be used to get the current thread list.
+A pointer to an array of type
+.Vt lwpid_t
+should be passed in
+.Fa addr ,
+with the array size specified by
+.Fa data .
+The return value from
+.Fn ptrace
+is the count of array entries filled in.
+.It Dv PT_SETSTEP
+This request will turn on single stepping of the specified process.
+Stepping is automatically disabled when a single step trap is caught.
+.It Dv PT_CLEARSTEP
+This request will turn off single stepping of the specified process.
+.It Dv PT_SUSPEND
+This request will suspend the specified thread.
+.It Dv PT_RESUME
+This request will resume the specified thread.
+.It Dv PT_TO_SCE
+This request will set the
+.Dv PTRACE_SCE
+event flag to trace all future system call entries and continue the process.
+The
+.Fa addr
+and
+.Fa data
+arguments are used the same as for
+.Dv PT_CONTINUE .
+.It Dv PT_TO_SCX
+This request will set the
+.Dv PTRACE_SCX
+event flag to trace all future system call exits and continue the process.
+The
+.Fa addr
+and
+.Fa data
+arguments are used the same as for
+.Dv PT_CONTINUE .
+.It Dv PT_SYSCALL
+This request will set the
+.Dv PTRACE_SYSCALL
+event flag to trace all future system call entries and exits and continue
+the process.
+The
+.Fa addr
+and
+.Fa data
+arguments are used the same as for
+.Dv PT_CONTINUE .
+.It Dv PT_GET_SC_ARGS
+For the thread which is stopped in either
+.Dv PL_FLAG_SCE
+or
+.Dv PL_FLAG_SCX
+state, that is, on entry or exit to a syscall,
+this request fetches the syscall arguments.
+.Pp
+The arguments are copied out into the buffer pointed to by the
+.Fa addr
+pointer, sequentially.
+Each syscall argument is stored as the machine word.
+Kernel copies out as many arguments as the syscall accepts,
+see the
+.Va pl_syscall_narg
+member of the
+.Vt struct ptrace_lwpinfo ,
+but not more than the
+.Fa data
+bytes in total are copied.
+.It Dv PT_GET_SC_RET
+Fetch the system call return values on exit from a syscall.
+This request is only valid for threads stopped in a syscall
+exit (the
+.Dv PL_FLAG_SCX
+state).
+The
+.Fa addr
+argument specifies a pointer to a
+.Vt "struct ptrace_sc_ret" ,
+which is defined as follows:
+.Bd -literal
+struct ptrace_sc_ret {
+ register_t sr_retval[2];
+ int sr_error;
+};
+.Ed
+.Pp
+The
+.Fa data
+argument is set to the size of the structure.
+.Pp
+If the system call completed successfully,
+.Va sr_error
+is set to zero and the return values of the system call are saved in
+.Va sr_retval .
+If the system call failed to execute,
+.Va sr_error
+field is set to a positive
+.Xr errno 2
+value.
+If the system call completed in an unusual fashion,
+.Va sr_error
+is set to a negative value:
+.Bl -tag -width EJUSTRETURN -compact
+.It Dv ERESTART
+System call will be restarted.
+.It Dv EJUSTRETURN
+System call completed sucessfully but did not set a return value
+.Po for example,
+.Xr setcontext 2
+and
+.Xr sigreturn 2
+.Pc .
+.El
+.It Dv PT_FOLLOW_FORK
+This request controls tracing for new child processes of a traced process.
+If
+.Fa data
+is non-zero,
+.Dv PTRACE_FORK
+is set in the traced process's event tracing mask.
+If
+.Fa data
+is zero,
+.Dv PTRACE_FORK
+is cleared from the traced process's event tracing mask.
+.It Dv PT_LWP_EVENTS
+This request controls tracing of LWP creation and destruction.
+If
+.Fa data
+is non-zero,
+.Dv PTRACE_LWP
+is set in the traced process's event tracing mask.
+If
+.Fa data
+is zero,
+.Dv PTRACE_LWP
+is cleared from the traced process's event tracing mask.
+.It Dv PT_GET_EVENT_MASK
+This request reads the traced process's event tracing mask into the
+integer pointed to by
+.Fa addr .
+The size of the integer must be passed in
+.Fa data .
+.It Dv PT_SET_EVENT_MASK
+This request sets the traced process's event tracing mask from the
+integer pointed to by
+.Fa addr .
+The size of the integer must be passed in
+.Fa data .
+.It Dv PT_VM_TIMESTAMP
+This request returns the generation number or timestamp of the memory map of
+the traced process as the return value from
+.Fn ptrace .
+This provides a low-cost way for the tracing process to determine if the
+VM map changed since the last time this request was made.
+.It Dv PT_VM_ENTRY
+This request is used to iterate over the entries of the VM map of the traced
+process.
+The
+.Fa addr
+argument specifies a pointer to a
+.Vt "struct ptrace_vm_entry" ,
+which is defined as follows:
+.Bd -literal
+struct ptrace_vm_entry {
+ int pve_entry;
+ int pve_timestamp;
+ u_long pve_start;
+ u_long pve_end;
+ u_long pve_offset;
+ u_int pve_prot;
+ u_int pve_pathlen;
+ long pve_fileid;
+ uint32_t pve_fsid;
+ char *pve_path;
+};
+.Ed
+.Pp
+The first entry is returned by setting
+.Va pve_entry
+to zero.
+Subsequent entries are returned by leaving
+.Va pve_entry
+unmodified from the value returned by previous requests.
+The
+.Va pve_timestamp
+field can be used to detect changes to the VM map while iterating over the
+entries.
+The tracing process can then take appropriate action, such as restarting.
+By setting
+.Va pve_pathlen
+to a non-zero value on entry, the pathname of the backing object is returned
+in the buffer pointed to by
+.Va pve_path ,
+provided the entry is backed by a vnode.
+The
+.Va pve_pathlen
+field is updated with the actual length of the pathname (including the
+terminating null character).
+The
+.Va pve_offset
+field is the offset within the backing object at which the range starts.
+The range is located in the VM space at
+.Va pve_start
+and extends up to
+.Va pve_end
+(inclusive).
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_COREDUMP
+This request creates a coredump for the stopped program.
+The
+.Fa addr
+argument specifies a pointer to a
+.Vt "struct ptrace_coredump" ,
+which is defined as follows:
+.Bd -literal
+struct ptrace_coredump {
+ int pc_fd;
+ uint32_t pc_flags;
+ off_t pc_limit;
+};
+.Ed
+The fields of the structure are:
+.Bl -tag -width pc_flags
+.It Dv pc_fd
+File descriptor to write the dump to.
+It must refer to a regular file, opened for writing.
+.It Dv pc_flags
+Flags.
+The following flags are defined:
+.Bl -tag -width PC_COMPRESS
+.It Dv PC_COMPRESS
+Request compression of the dump.
+.It Dv PC_ALL
+Include non-dumpable entries into the dump.
+The dumper ignores
+.Dv MAP_NOCORE
+flag of the process map entry, but device mappings are not dumped even with
+.Dv PC_ALL
+set.
+.El
+.It Dv pc_limit
+Maximum size of the coredump.
+Specify zero for no limit.
+.El
+.Pp
+The size of
+.Vt "struct ptrace_coredump"
+must be passed in
+.Fa data .
+.It Dv PT_SC_REMOTE
+Request to execute a syscall in the context of the traced process,
+in the specified thread.
+The
+.Fa addr
+argument must point to the
+.Vt "struct ptrace_sc_remote" ,
+which describes the requested syscall and its arguments, and receives
+the result.
+The size of
+.Vt "struct ptrace_sc_remote"
+must be passed in
+.Fa data.
+.Bd -literal
+struct ptrace_sc_remote {
+ struct ptrace_sc_ret pscr_ret;
+ u_int pscr_syscall;
+ u_int pscr_nargs;
+ u_long *pscr_args;
+};
+.Ed
+The
+.Dv pscr_syscall
+contains the syscall number to execute, the
+.Dv pscr_nargs
+is the number of supplied arguments, which are supplied in the
+.Dv pscr_args
+array.
+Result of the execution is returned in the
+.Dv pscr_ret
+member.
+Note that the request and its result do not affect the returned value from
+the currently executed syscall, if any.
+.El
+.Sh PT_COREDUMP and PT_SC_REMOTE usage
+The process must be stopped before dumping or initiating a remote system call.
+A single thread in the target process is temporarily unsuspended
+in the kernel to perform the action.
+If the
+.Nm
+call fails before a thread is unsuspended, there is no event to
+.Xr waitpid 2
+for.
+If a thread was unsuspended, it will stop again before the
+.Nm
+call returns, and the process must be waited upon using
+.Xr waitpid 2
+to consume the new stop event.
+Since it is hard to deduce whether a thread was unsuspended before
+an error occurred, it is recommended to unconditionally perform
+.Xr waitpid 2
+with
+.Dv WNOHANG
+flag after
+.Dv PT_COREDUMP
+and
+.Dv PT_SC_REMOTE ,
+and silently accept zero result from it.
+.Pp
+For
+.Dv PT_SC_REMOTE ,
+the selected thread must be stopped in the safe place, which is
+currently defined as a syscall exit, or a return from kernel to
+user mode (basically, a signal handler call place).
+Kernel returns
+.Er EBUSY
+status if attempt is made to execute remote syscall at unsafe stop.
+.Pp
+Note that neither
+.Dv kern.trap_enotcap
+sysctl setting, nor the corresponding
+.Xr procctl 2
+flag
+.Dv PROC_TRAPCAP_CTL_ENABLE
+are obeyed during the execution of the syscall by
+.Dv PT_SC_REMOTE .
+In other words,
+.Dv SIGTRAP
+signal is not sent to a process executing in capability mode,
+which violated a mode access restriction.
+.Pp
+Note that due to the mode of execution for the remote syscall, in
+particular, the setting where only one thread is allowed to run,
+the syscall might block on resources owned by suspended threads.
+This might result in the target process deadlock.
+In this situation, the only way out is to kill the target.
+.Sh ARM MACHINE-SPECIFIC REQUESTS
+.Bl -tag -width "Dv PT_SETVFPREGS"
+.It Dv PT_GETVFPREGS
+Return the thread's
+.Dv VFP
+machine state in the buffer pointed to by
+.Fa addr .
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_SETVFPREGS
+Set the thread's
+.Dv VFP
+machine state from the buffer pointed to by
+.Fa addr .
+.Pp
+The
+.Fa data
+argument is ignored.
+.El
+.Sh x86 MACHINE-SPECIFIC REQUESTS
+.Bl -tag -width "Dv PT_GETXSTATE_INFO"
+.It Dv PT_GETXMMREGS
+Copy the XMM FPU state into the buffer pointed to by the
+argument
+.Fa addr .
+The buffer has the same layout as the 32-bit save buffer for the
+machine instruction
+.Dv FXSAVE .
+.Pp
+This request is only valid for i386 programs, both on native 32-bit
+systems and on amd64 kernels.
+For 64-bit amd64 programs, the XMM state is reported as part of
+the FPU state returned by the
+.Dv PT_GETFPREGS
+request.
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_SETXMMREGS
+Load the XMM FPU state for the thread from the buffer pointed to
+by the argument
+.Fa addr .
+The buffer has the same layout as the 32-bit load buffer for the
+machine instruction
+.Dv FXRSTOR .
+.Pp
+As with
+.Dv PT_GETXMMREGS ,
+this request is only valid for i386 programs.
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_GETXSTATE_INFO
+Report which XSAVE FPU extensions are supported by the CPU
+and allowed in userspace programs.
+The
+.Fa addr
+argument must point to a variable of type
+.Vt struct ptrace_xstate_info ,
+which contains the information on the request return.
+.Vt struct ptrace_xstate_info
+is defined as follows:
+.Bd -literal
+struct ptrace_xstate_info {
+ uint64_t xsave_mask;
+ uint32_t xsave_len;
+};
+.Ed
+The
+.Dv xsave_mask
+field is a bitmask of the currently enabled extensions.
+The meaning of the bits is defined in the Intel and AMD
+processor documentation.
+The
+.Dv xsave_len
+field reports the length of the XSAVE area for storing the hardware
+state for currently enabled extensions in the format defined by the x86
+.Dv XSAVE
+machine instruction.
+.Pp
+The
+.Fa data
+argument value must be equal to the size of the
+.Vt struct ptrace_xstate_info .
+.It Dv PT_GETXSTATE
+Return the content of the XSAVE area for the thread.
+The
+.Fa addr
+argument points to the buffer where the content is copied, and the
+.Fa data
+argument specifies the size of the buffer.
+The kernel copies out as much content as allowed by the buffer size.
+The buffer layout is specified by the layout of the save area for the
+.Dv XSAVE
+machine instruction.
+.It Dv PT_SETXSTATE
+Load the XSAVE state for the thread from the buffer specified by the
+.Fa addr
+pointer.
+The buffer size is passed in the
+.Fa data
+argument.
+The buffer must be at least as large as the
+.Vt struct savefpu
+(defined in
+.Pa x86/fpu.h )
+to allow the complete x87 FPU and XMM state load.
+It must not be larger than the XSAVE state length, as reported by the
+.Dv xsave_len
+field from the
+.Vt struct ptrace_xstate_info
+of the
+.Dv PT_GETXSTATE_INFO
+request.
+Layout of the buffer is identical to the layout of the load area for the
+.Dv XRSTOR
+machine instruction.
+.It Dv PT_GETFSBASE
+Return the value of the base used when doing segmented
+memory addressing using the %fs segment register.
+The
+.Fa addr
+argument points to an
+.Vt unsigned long
+variable where the base value is stored.
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_GETGSBASE
+Like the
+.Dv PT_GETFSBASE
+request, but returns the base for the %gs segment register.
+.It Dv PT_SETFSBASE
+Set the base for the %fs segment register to the value pointed to
+by the
+.Fa addr
+argument.
+.Fa addr
+must point to the
+.Vt unsigned long
+variable containing the new base.
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_SETGSBASE
+Like the
+.Dv PT_SETFSBASE
+request, but sets the base for the %gs segment register.
+.El
+.Sh PowerPC MACHINE-SPECIFIC REQUESTS
+.Bl -tag -width "Dv PT_SETVRREGS"
+.It Dv PT_GETVRREGS
+Return the thread's
+.Dv ALTIVEC
+machine state in the buffer pointed to by
+.Fa addr .
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_SETVRREGS
+Set the thread's
+.Dv ALTIVEC
+machine state from the buffer pointed to by
+.Fa addr .
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_GETVSRREGS
+Return doubleword 1 of the thread's
+.Dv VSX
+registers VSR0-VSR31 in the buffer pointed to by
+.Fa addr .
+.Pp
+The
+.Fa data
+argument is ignored.
+.It Dv PT_SETVSRREGS
+Set doubleword 1 of the thread's
+.Dv VSX
+registers VSR0-VSR31 from the buffer pointed to by
+.Fa addr .
+.Pp
+The
+.Fa data
+argument is ignored.
+.El
+.Pp
+Additionally, other machine-specific requests can exist.
+.Sh RETURN VALUES
+Most requests return 0 on success and \-1 on error.
+Some requests can cause
+.Fn ptrace
+to return
+\-1
+as a non-error value, among them are
+.Dv PT_READ_I
+and
+.Dv PT_READ_D ,
+which return the value read from the process memory on success.
+To disambiguate,
+.Va errno
+can be set to 0 before the call and checked afterwards.
+.Pp
+The current
+.Fn ptrace
+implementation always sets
+.Va errno
+to 0 before calling into the kernel, both for historic reasons and for
+consistency with other operating systems.
+It is recommended to assign zero to
+.Va errno
+explicitly for forward compatibility.
+.Sh ERRORS
+The
+.Fn ptrace
+system call may fail if:
+.Bl -tag -width Er
+.It Bq Er ESRCH
+.Bl -bullet -compact
+.It
+No process having the specified process ID exists.
+.El
+.It Bq Er EINVAL
+.Bl -bullet -compact
+.It
+A process attempted to use
+.Dv PT_ATTACH
+on itself.
+.It
+The
+.Fa request
+argument
+was not one of the legal requests.
+.It
+The signal number
+(in
+.Fa data )
+to
+.Dv PT_CONTINUE
+was neither 0 nor a legal signal number.
+.It
+.Dv PT_GETREGS ,
+.Dv PT_SETREGS ,
+.Dv PT_GETFPREGS ,
+.Dv PT_SETFPREGS ,
+.Dv PT_GETDBREGS ,
+or
+.Dv PT_SETDBREGS
+was attempted on a process with no valid register set.
+(This is normally true only of system processes.)
+.It
+.Dv PT_VM_ENTRY
+was given an invalid value for
+.Fa pve_entry .
+This can also be caused by changes to the VM map of the process.
+.It
+The size (in
+.Fa data )
+provided to
+.Dv PT_LWPINFO
+was less than or equal to zero, or larger than the
+.Vt ptrace_lwpinfo
+structure known to the kernel.
+.It
+The size (in
+.Fa data )
+provided to the x86-specific
+.Dv PT_GETXSTATE_INFO
+request was not equal to the size of the
+.Vt struct ptrace_xstate_info .
+.It
+The size (in
+.Fa data )
+provided to the x86-specific
+.Dv PT_SETXSTATE
+request was less than the size of the x87 plus the XMM save area.
+.It
+The size (in
+.Fa data )
+provided to the x86-specific
+.Dv PT_SETXSTATE
+request was larger than returned in the
+.Dv xsave_len
+member of the
+.Vt struct ptrace_xstate_info
+from the
+.Dv PT_GETXSTATE_INFO
+request.
+.It
+The base value, provided to the amd64-specific requests
+.Dv PT_SETFSBASE
+or
+.Dv PT_SETGSBASE ,
+pointed outside of the valid user address space.
+This error will not occur in 32-bit programs.
+.El
+.It Bq Er EBUSY
+.Bl -bullet -compact
+.It
+.Dv PT_ATTACH
+was attempted on a process that was already being traced.
+.It
+A request attempted to manipulate a process that was being traced by
+some process other than the one making the request.
+.It
+A request
+(other than
+.Dv PT_ATTACH )
+specified a process that was not stopped.
+.El
+.It Bq Er EPERM
+.Bl -bullet -compact
+.It
+A request
+(other than
+.Dv PT_ATTACH )
+attempted to manipulate a process that was not being traced at all.
+.It
+An attempt was made to use
+.Dv PT_ATTACH
+on a process in violation of the requirements listed under
+.Dv PT_ATTACH
+above.
+.El
+.It Bq Er ENOENT
+.Bl -bullet -compact
+.It
+.Dv PT_VM_ENTRY
+previously returned the last entry of the memory map.
+No more entries exist.
+.El
+.It Bq Er ENOMEM
+.Bl -bullet -compact
+.It
+A
+.Dv PT_READ_I,
+.Dv PT_READ_D,
+.Dv PT_WRITE_I, or
+.Dv PT_WRITE_D
+request attempted to access an invalid address, or a memory allocation failure
+occurred when accessing process memory.
+.El
+.It Bq Er ENAMETOOLONG
+.Bl -bullet -compact
+.It
+.Dv PT_VM_ENTRY
+cannot return the pathname of the backing object because the buffer is not big
+enough.
+.Fa pve_pathlen
+holds the minimum buffer size required on return.
+.El
+.El
+.Sh SEE ALSO
+.Xr execve 2 ,
+.Xr sigaction 2 ,
+.Xr wait 2 ,
+.Xr execv 3 ,
+.Xr i386_clr_watch 3 ,
+.Xr i386_set_watch 3
+.Sh HISTORY
+The
+.Fn ptrace
+function appeared in
+.At v6 .