| PTRACE(2) | System Calls Manual | PTRACE(2) |
ptrace — process
tracing and debugging
#include
<sys/types.h>
#include <sys/ptrace.h>
int
ptrace(int
request, pid_t pid,
caddr_t addr,
int data);
ptrace()
provides tracing and debugging facilities. It allows one process (the
tracing
process) to control another (the
traced
process). Most of the time, the traced process runs normally, but when it
receives a signal (see
sigaction(2)), it stops. The
tracing process is expected to notice this via
wait(2) or the delivery of a
SIGCHLD signal, examine the state of the stopped
process, and cause it to terminate or continue as appropriate.
ptrace() is the mechanism by which all this happens.
ptrace() is only available on kernels compiled with
the PTRACE option.
The 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
ptrace()
calls are made by the tracing process, and the pid
argument specifies the process ID of the traced process.
request can be:
PT_TRACE_MEptrace().) When a process has used this request
and calls execve(2) or any of
the routines built on it (such as
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.PT_READ_I,
PT_READ_Dptrace() has allowed for machines with distinct
address spaces for instruction and data, which is why there are two
requests: conceptually, PT_READ_I reads from the
instruction space and PT_READ_D reads from the
data space. In the current OpenBSD implementation,
these two requests operate in the same address space. The
addr argument specifies the address (in the traced
process' 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 ptrace().PT_WRITE_I,
PT_WRITE_DPT_READ_I and
PT_READ_D, except that they write rather than
read. PT_WRITE_I may be necessary to ensure that
instruction caches are flushed appropriately. The
data argument supplies the value to be written.PT_CONTINUE(caddr_t)1 to
indicate that execution is to pick up where it left off.
data provides a signal number to be delivered to the
traced process as it resumes execution, or 0 if no signal is to be
sent.PT_KILLPT_CONTINUE
had been used with SIGKILL given as the signal to
be delivered.PT_ATTACHkern.global_ptrace sysctl is 0, then the target
process must be a descendant of the tracing process. (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.PT_DETACHPT_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.PT_IOPT_READ_D, PT_WRITE_D,
PT_READ_I and PT_WRITE_I.
The I/O request is encoded in a “struct
ptrace_io_desc” defined as:
struct ptrace_io_desc {
int piod_op;
void *piod_offs;
void *piod_addr;
size_t piod_len;
};
Where piod_offs is the offset within the traced process where the I/O operation should be made, piod_addr is the buffer in the parent and piod_len is the length of the I/O request. The piod_op member specifies what operation needs to be done. Possible values are:
See also the description of
PT_READ_I for the difference between D and I
spaces. The PIOD_READ_AUXV operation can be used
to read from the ELF auxiliary vector. A pointer to the descriptor is
passed in addr. On return the
piod_len field in the descriptor will be updated
with the actual number of bytes transferred. If the requested I/O could
not be successfully performed,
ptrace()
will return -1 and set
errno.
PT_SET_EVENT_MASKstruct ptrace_event” defined as:
typedef struct ptrace_event {
int pe_set_event;
} ptrace_event_t;
Where pe_set_event is the set of events to be reported. This set is formed by OR'ing together the following values:
A pointer to this structure is passed in
addr. The data argument
should be set to sizeof(struct
ptrace_event).
PT_GET_EVENT_MASKstruct ptrace_event” pointed to by
addr. The data argument should
be set to sizeof(struct ptrace_event).PT_GET_PROCESS_STATEstruct ptrace_state” defined as:
typedef struct ptrace_state {
int pe_report_event;
pid_t pe_other_pid;
} ptrace_state_t;
Where pe_report_event is the event being
reported. If the event being reported is
PTRACE_FORK, pe_other_pid
will be set to the process ID of the other end of the fork. A pointer to
this structure is passed in addr. The
data argument should be set to
sizeof(struct ptrace_state).
PT_GET_THREAD_FIRSTstruct ptrace_thread_state”
pointed to by addr. The data
argument should be set to sizeof(struct
ptrace_thread_state).PT_GET_THREAD_NEXTPT_GET_THREAD_FIRST,
except it returns the thread ID of the subsequent thread. The
“struct ptrace_thread_state” pointed
to by addr must be initialized by a previous
PT_GET_THREAD_FIRST or
PT_GET_THREAD_NEXT request.Additionally, machine-specific requests can exist. Depending on the architecture, the following requests may be available under OpenBSD:
PT_GETREGS
(all platforms)struct reg” (defined in
<machine/reg.h>) pointed
to by addr.PT_SETREGS
(all platforms)PT_GETREGS; it
loads the traced process' machine registers from the
“struct reg” (defined in
<machine/reg.h>) pointed
to by addr.PT_STEP
(not available on sparc64)PT_CONTINUE; however, execution stops as soon as
possible after execution of at least one instruction (single-step).PT_GETFPREGS
(not available on luna88k or mips64)struct fpreg” (defined in
<machine/reg.h>) pointed
to by addr.PT_SETFPREGS
(not available on luna88k or mips64)PT_GETFPREGS; it
loads the traced process' floating-point registers from the
“struct fpreg” (defined in
<machine/reg.h>) pointed
to by addr.PT_GETXMMREGS
(i386 only)struct xmmregs” (defined in
<machine/reg.h>) pointed
to by addr.PT_SETXMMREGS
(i386 only)PT_GETXMMREGS; it
loads the traced process' XMM registers from the
“struct xmmregs” (defined in
<machine/reg.h>) pointed
to by addr.PT_WCOOKIE
(sparc64 only)PT_GETXSTATE_INFO
(amd64 only)struct
ptrace_xstate_info” defined as follows:
struct ptrace_xstate_info {
uint64_t xsave_mask;
uint32_t xsave_len;
};
The xsave_mask field denotes the enabled
XSAVE components. The xsave_len field denotes the
size of XSAVE area intended to be used with the
PT_GETXSTATE and
PT_SETXSTATE requests.
A pointer to “struct
ptrace_xstate_info” must be passed in
addr and the data argument
must be set to sizeof(struct
ptrace_xstate_info).
PT_GETXSTATE
(amd64 only)PT_GETXSTATE_INFO request. The
data argument must reflect the same length.PT_SETXSTATE
(amd64 only)PT_GETXSTATE_INFO request. The
data argument must reflect the same length.Some requests can cause ptrace() to return
-1 as a non-error value; to disambiguate,
errno is set to zero and this should be checked. The
possible errors are:
ESRCH]EINVAL]PT_ATTACH on
itself.PT_CONTINUE was neither 0 nor a legal signal
number.PT_GETREGS,
PT_SETREGS,
PT_GETFPREGS, or
PT_SETFPREGS was attempted on a process with
no valid register set. (This is normally true only of system
processes.)EBUSY]PT_ATTACH
was attempted on a process that was already being traced.PT_ATTACH) specified a
process that wasn't stopped and waited for.EPERM]PT_ATTACH) attempted to
manipulate a process that wasn't being traced at all.PT_ATTACH on a
process in violation of the requirements listed under
PT_ATTACH above.PT_ATTACH on a
system process.ENOTSUP]PT_GETXSTATE_INFO,
PT_GETXSTATE, or
PT_SETXSTATE was attempted on a CPU lacking
support for XSAVE.The ptrace() system call first appeared in
Version 6 AT&T UNIX.
On several RISC architectures (such as luna88k and sparc64), the
PC is set to the provided PC value for PT_CONTINUE
and similar calls, and the remainder of the execution pipeline registers are
set to the following instructions, even if the instruction at PC is a branch
instruction. Using PT_GETREGS and
PT_SETREGS to modify the PC, passing
(caddr_t)1 to ptrace(),
should be able to sidestep this.
| November 27, 2024 | openbsd |