ptrace (2) Linux Manual Page
NAME
ptrace – process trace
SYNOPSIS
#include <sys/ptrace.h>
long ptrace(enum __ptrace_request request, pid_t pid,
void *addr, void *data);
DESCRIPTION
The ptrace() system call provides a means by which one process (the "tracer") may observe and control the execution of another process (the "tracee"), and examine and change the tracee’s memory and registers. It is primarily used to implement breakpoint debugging and system call tracing.
A tracee first needs to be attached to the tracer. Attachment and subsequent commands are per thread: in a multithreaded process, every thread can be individually attached to a (potentially different) tracer, or left not attached and thus not debugged. Therefore, "tracee" always means "(one) thread", never "a (possibly multithreaded) process". Ptrace commands are always sent to a specific tracee using a call of the form
where pid is the thread ID of the corresponding Linux thread.
(Note that in this page, a "multithreaded process" means a thread group consisting of threads created using the clone(2) CLONE_THREAD flag.)
A process can initiate a trace by calling fork(2) and having the resulting child do a PTRACE_TRACEME, followed (typically) by an execve(2). Alternatively, one process may commence tracing another process using PTRACE_ATTACH or PTRACE_SEIZE.
While being traced, the tracee will stop each time a signal is delivered, even if the signal is being ignored. (An exception is SIGKILL, which has its usual effect.) The tracer will be notified at its next call to waitpid(2) (or one of the related "wait" system calls); that call will return a status value containing information that indicates the cause of the stop in the tracee. While the tracee is stopped, the tracer can use various ptrace requests to inspect and modify the tracee. The tracer then causes the tracee to continue, optionally ignoring the delivered signal (or even delivering a different signal instead).
If the PTRACE_O_TRACEEXEC option is not in effect, all successful calls to execve(2) by the traced process will cause it to be sent a SIGTRAP signal, giving the parent a chance to gain control before the new program begins execution.
When the tracer is finished tracing, it can cause the tracee to continue executing in a normal, untraced mode via PTRACE_DETACH.
The value of request determines the action to be performed:
PTRACE_TRACEME- Indicate that this process is to be traced by its parent. A process probably shouldn’t make this request if its parent isn’t expecting to trace it. (pid, addr, and data are ignored.)
- The
PTRACE_TRACEMErequest is used only by the tracee; the remaining requests are used only by the tracer. In the following requests, pid specifies the thread ID of the tracee to be acted on. For requests other thanPTRACE_ATTACH,PTRACE_SEIZE,PTRACE_INTERRUPT, andPTRACE_KILL, the tracee must be stopped. PTRACE_PEEKTEXT,PTRACE_PEEKDATA- Read a word at the address addr in the tracee’s memory, returning the word as the result of the
ptrace() call. Linux does not have separate text and data address spaces, so these two requests are currently equivalent. (data is ignored; but see NOTES.) PTRACE_PEEKUSER- Read a word at offset addr in the tracee’s USER area, which holds the registers and other information about the process (see <sys/user.h>). The word is returned as the result of the
ptrace() call. Typically, the offset must be word-aligned, though this might vary by architecture. See NOTES. (data is ignored; but see NOTES.) PTRACE_POKETEXT,PTRACE_POKEDATA- Copy the word data to the address addr in the tracee’s memory. As for
PTRACE_PEEKTEXTandPTRACE_PEEKDATA, these two requests are currently equivalent. PTRACE_POKEUSER- Copy the word data to offset addr in the tracee’s USER area. As for
PTRACE_PEEKUSER, the offset must typically be word-aligned. In order to maintain the integrity of the kernel, some modifications to the USER area are disallowed. PTRACE_GETREGS,PTRACE_GETFPREGS- Copy the tracee’s general-purpose or floating-point registers, respectively, to the address data in the tracer. See <sys/user.h> for information on the format of this data. (addr is ignored.) Note that SPARC systems have the meaning of data and addr reversed; that is, data is ignored and the registers are copied to the address addr.
PTRACE_GETREGSandPTRACE_GETFPREGSare not present on all architectures. PTRACE_GETREGSET(since Linux 2.6.34)- Read the tracee’s registers. addr specifies, in an architecture-dependent way, the type of registers to be read.
NT_PRSTATUS(with numerical value 1) usually results in reading of general-purpose registers. If the CPU has, for example, floating-point and/or vector registers, they can be retrieved by setting addr to the correspondingNT_fooconstant. data points to astruct iovec, which describes the destination buffer’s location and length. On return, the kernel modifiesiov.lento indicate the actual number of bytes returned. PTRACE_SETREGS,PTRACE_SETFPREGS- Modify the tracee’s general-purpose or floating-point registers, respectively, from the address data in the tracer. As for
PTRACE_POKEUSER, some general-purpose register modifications may be disallowed. (addr is ignored.) Note that SPARC systems have the meaning of data and addr reversed; that is, data is ignored and the registers are copied from the address addr.PTRACE_SETREGSandPTRACE_SETFPREGSare not present on all architectures. PTRACE_SETREGSET(since Linux 2.6.34)- Modify the tracee’s registers. The meaning of addr and data is analogous to
PTRACE_GETREGSET. PTRACE_GETSIGINFO(since Linux 2.3.99-pre6)- Retrieve information about the signal that caused the stop. Copy a siginfo_t structure (see
sigaction(2)) from the tracee to the address data in the tracer. (addr is ignored.) PTRACE_SETSIGINFO(since Linux 2.3.99-pre6)- Set signal information: copy a siginfo_t structure from the address data in the tracer to the tracee. This will affect only signals that would normally be delivered to the tracee and were caught by the tracer. It may be difficult to tell these normal signals from synthetic signals generated by
ptrace() itself. (addr is ignored.) PTRACE_PEEKSIGINFO(since Linux 3.10)- Retrieve siginfo_t structures without removing signals from a queue. addr points to a ptrace_peeksiginfo_args structure that specifies the ordinal position from which copying of signals should start, and the number of signals to copy. siginfo_t structures are copied into the buffer pointed to by data. The return value contains the number of copied signals (zero indicates that there is no signal corresponding to the specified ordinal position). Within the returned siginfo structures, the si_code field includes information (
__SI_CHLD,__SI_FAULT, etc.) that are not otherwise exposed to user space.
struct ptrace_peeksiginfo_args {
- Currently, there is only one flag,
PTRACE_PEEKSIGINFO_SHARED, for dumping signals from the process-wide signal queue. If this flag is not set, signals are read from the per-thread queue of the specified thread. PTRACE_GETSIGMASK(since Linux 3.11)- Place a copy of the mask of blocked signals (see
sigprocmask(2)) in the buffer pointed to by data, which should be a pointer to a buffer of type sigset_t. The addr argument contains the size of the buffer pointed to by data (i.e., sizeof(sigset_t)). PTRACE_SETSIGMASK(since Linux 3.11)- Change the mask of blocked signals (see
sigprocmask(2)) to the value specified in the buffer pointed to by data, which should be a pointer to a buffer of type sigset_t. The addr argument contains the size of the buffer pointed to by data (i.e., sizeof(sigset_t)). PTRACE_SETOPTIONS(since Linux 2.4.6; see BUGS for caveats)- Set ptrace options from data. (addr is ignored.) data is interpreted as a bit mask of options, which are specified by the following flags:
-
PTRACE_O_EXITKILL(since Linux 3.8)- Send a
SIGKILLsignal to the tracee if the tracer exits. This option is useful for ptrace jailers that want to ensure that tracees can never escape the tracer’s control. PTRACE_O_TRACECLONE(since Linux 2.5.46)- Stop the tracee at the next
clone(2) and automatically start tracing the newly cloned process, which will start with aSIGSTOP, orPTRACE_EVENT_STOPifPTRACE_SEIZEwas used. Awaitpid(2) by the tracer will return a status value such that -
status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8))
- The PID of the new process can be retrieved with
PTRACE_GETEVENTMSG. - This option may not catch
clone(2) calls in all cases. If the tracee callsclone(2) with theCLONE_VFORKflag,PTRACE_EVENT_VFORKwill be delivered instead ifPTRACE_O_TRACEVFORKis set; otherwise if the tracee callsclone(2) with the exit signal set toSIGCHLD,PTRACE_EVENT_FORKwill be delivered ifPTRACE_O_TRACEFORKis set. PTRACE_O_TRACEEXEC(since Linux 2.5.46)- Stop the tracee at the next
execve(2). Awaitpid(2) by the tracer will return a status value such that -
status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))
- If the execing thread is not a thread group leader, the thread ID is reset to thread group leader’s ID before this stop. Since Linux 3.0, the former thread ID can be retrieved with
PTRACE_GETEVENTMSG. PTRACE_O_TRACEEXIT(since Linux 2.5.60)- Stop the tracee at exit. A
waitpid(2) by the tracer will return a status value such that -
status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))
- The tracee’s exit status can be retrieved with
PTRACE_GETEVENTMSG. - The tracee is stopped early during process exit, when registers are still available, allowing the tracer to see where the exit occurred, whereas the normal exit notification is done after the process is finished exiting. Even though context is available, the tracer cannot prevent the exit from happening at this point.
PTRACE_O_TRACEFORK(since Linux 2.5.46)- Stop the tracee at the next
fork(2) and automatically start tracing the newly forked process, which will start with aSIGSTOP, orPTRACE_EVENT_STOPifPTRACE_SEIZEwas used. Awaitpid(2) by the tracer will return a status value such that -
status>>8 == (SIGTRAP | (PTRACE_EVENT_FORK<<8))
- The PID of the new process can be retrieved with
PTRACE_GETEVENTMSG. PTRACE_O_TRACESYSGOOD(since Linux 2.4.6)- When delivering system call traps, set bit 7 in the signal number (i.e., deliver SIGTRAP|0x80). This makes it easy for the tracer to distinguish normal traps from those caused by a system call.
PTRACE_O_TRACEVFORK(since Linux 2.5.46)- Stop the tracee at the next
vfork(2) and automatically start tracing the newly vforked process, which will start with aSIGSTOP, orPTRACE_EVENT_STOPifPTRACE_SEIZEwas used. Awaitpid(2) by the tracer will return a status value such that -
status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK<<8))
- The PID of the new process can be retrieved with
PTRACE_GETEVENTMSG. PTRACE_O_TRACEVFORKDONE(since Linux 2.5.60)- Stop the tracee at the completion of the next
vfork(2). Awaitpid(2) by the tracer will return a status value such that -
status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK_DONE<<8))
- The PID of the new process can (since Linux 2.6.18) be retrieved with
PTRACE_GETEVENTMSG. PTRACE_O_TRACESECCOMP(since Linux 3.5)- Stop the tracee when a
seccomp(2)SECCOMP_RET_TRACErule is triggered. Awaitpid(2) by the tracer will return a status value such that -
status>>8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP<<8))
- While this triggers a
PTRACE_EVENTstop, it is similar to a syscall-enter-stop. For details, see the note onPTRACE_EVENT_SECCOMPbelow. The seccomp event message data (from theSECCOMP_RET_DATAportion of the seccomp filter rule) can be retrieved withPTRACE_GETEVENTMSG. PTRACE_O_SUSPEND_SECCOMP(since Linux 4.3)- Suspend the tracee’s seccomp protections. This applies regardless of mode, and can be used when the tracee has not yet installed seccomp filters. That is, a valid use case is to suspend a tracee’s seccomp protections before they are installed by the tracee, let the tracee install the filters, and then clear this flag when the filters should be resumed. Setting this option requires that the tracer have the
CAP_SYS_ADMINcapability, not have any seccomp protections installed, and not havePTRACE_O_SUSPEND_SECCOMPset on itself.
PTRACE_GETEVENTMSG(since Linux 2.5.46)- Retrieve a message (as an unsigned long) about the ptrace event that just happened, placing it at the address data in the tracer. For
PTRACE_EVENT_EXIT, this is the tracee’s exit status. ForPTRACE_EVENT_FORK,PTRACE_EVENT_VFORK,PTRACE_EVENT_VFORK_DONE, andPTRACE_EVENT_CLONE, this is the PID of the new process. ForPTRACE_EVENT_SECCOMP, this is theseccomp(2) filter’sSECCOMP_RET_DATAassociated with the triggered rule. (addr is ignored.) PTRACE_CONT- Restart the stopped tracee process. If data is nonzero, it is interpreted as the number of a signal to be delivered to the tracee; otherwise, no signal is delivered. Thus, for example, the tracer can control whether a signal sent to the tracee is delivered or not. (addr is ignored.)
PTRACE_SYSCALL,PTRACE_SINGLESTEP- Restart the stopped tracee as for
PTRACE_CONT, but arrange for the tracee to be stopped at the next entry to or exit from a system call, or after execution of a single instruction, respectively. (The tracee will also, as usual, be stopped upon receipt of a signal.) From the tracer’s perspective, the tracee will appear to have been stopped by receipt of aSIGTRAP. So, forPTRACE_SYSCALL, for example, the idea is to inspect the arguments to the system call at the first stop, then do anotherPTRACE_SYSCALLand inspect the return value of the system call at the second stop. The data argument is treated as forPTRACE_CONT. (addr is ignored.) PTRACE_SET_SYSCALL(since Linux 2.6.16)- When in syscall-enter-stop, change the number of the system call that is about to be executed to the number specified in the data argument. The addr argument is ignored. This request is currently supported only on arm (and arm64, though only for backwards compatibility), but most other architectures have other means of accomplishing this (usually by changing the register that the userland code passed the system call number in).
PTRACE_SYSEMU,PTRACE_SYSEMU_SINGLESTEP(since Linux 2.6.14)- For
PTRACE_SYSEMU, continue and stop on entry to the next system call, which will not be executed. See the documentation on syscall-stops below. ForPTRACE_SYSEMU_SINGLESTEP, do the same but also singlestep if not a system call. This call is used by programs like User Mode Linux that want to emulate all the tracee’s system calls. The data argument is treated as forPTRACE_CONT. The addr argument is ignored. These requests are currently supported only on x86. PTRACE_LISTEN(since Linux 3.4)- Restart the stopped tracee, but prevent it from executing. The resulting state of the tracee is similar to a process which has been stopped by a
SIGSTOP(or other stopping signal). See the "group-stop" subsection for additional information.PTRACE_LISTENworks only on tracees attached byPTRACE_SEIZE. PTRACE_KILL- Send the tracee a
SIGKILLto terminate it. (addr and data are ignored.) - This operation is deprecated; do not use it! Instead, send a
SIGKILLdirectly usingkill(2) ortgkill(2). The problem withPTRACE_KILLis that it requires the tracee to be in signal-delivery-stop, otherwise it may not work (i.e., may complete successfully but won’t kill the tracee). By contrast, sending aSIGKILLdirectly has no such limitation. PTRACE_INTERRUPT(since Linux 3.4)- Stop a tracee. If the tracee is running or sleeping in kernel space and
PTRACE_SYSCALLis in effect, the system call is interrupted and syscall-exit-stop is reported. (The interrupted system call is restarted when the tracee is restarted.) If the tracee was already stopped by a signal andPTRACE_LISTENwas sent to it, the tracee stops withPTRACE_EVENT_STOPand WSTOPSIG(status) returns the stop signal. If any other ptrace-stop is generated at the same time (for example, if a signal is sent to the tracee), this ptrace-stop happens. If none of the above applies (for example, if the tracee is running in user space), it stops withPTRACE_EVENT_STOPwith WSTOPSIG(status) ==SIGTRAP.PTRACE_INTERRUPTonly works on tracees attached byPTRACE_SEIZE. PTRACE_ATTACH- Attach to the process specified in pid, making it a tracee of the calling process. The tracee is sent a
SIGSTOP, but will not necessarily have stopped by the completion of this call; usewaitpid(2) to wait for the tracee to stop. See the "Attaching and detaching" subsection for additional information. (addr and data are ignored.) - Permission to perform a
PTRACE_ATTACHis governed by a ptrace access modePTRACE_MODE_ATTACH_REALCREDScheck; see below. PTRACE_SEIZE(since Linux 3.4)- Attach to the process specified in pid, making it a tracee of the calling process. Unlike
PTRACE_ATTACH,PTRACE_SEIZEdoes not stop the process. Group-stops are reported asPTRACE_EVENT_STOPand WSTOPSIG(status) returns the stop signal. Automatically attached children stop withPTRACE_EVENT_STOPand WSTOPSIG(status) returnsSIGTRAPinstead of havingSIGSTOPsignal delivered to them.execve(2) does not deliver an extraSIGTRAP. Only aPTRACE_SEIZEd process can acceptPTRACE_INTERRUPTandPTRACE_LISTENcommands. The "seized" behavior just described is inherited by children that are automatically attached usingPTRACE_O_TRACEFORK,PTRACE_O_TRACEVFORK, andPTRACE_O_TRACECLONE. addr must be zero. data contains a bit mask of ptrace options to activate immediately. - Permission to perform a
PTRACE_SEIZEis governed by a ptrace access modePTRACE_MODE_ATTACH_REALCREDScheck; see below. PTRACE_SECCOMP_GET_FILTER(since Linux 4.4)- This operation allows the tracer to dump the tracee’s classic BPF filters.
- addr is an integer specifying the index of the filter to be dumped. The most recently installed filter has the index 0. If addr is greater than the number of installed filters, the operation fails with the error
ENOENT. - data is either a pointer to a struct sock_filter array that is large enough to store the BPF program, or NULL if the program is not to be stored.
- Upon success, the return value is the number of instructions in the BPF program. If data was NULL, then this return value can be used to correctly size the struct sock_filter array passed in a subsequent call.
- This operation fails with the error
EACCESif the caller does not have theCAP_SYS_ADMINcapability or if the caller is in strict or filter seccomp mode. If the filter referred to by addr is not a classic BPF filter, the operation fails with the errorEMEDIUMTYPE. - This operation is available if the kernel was configured with both the
CONFIG_SECCOMP_FILTERand theCONFIG_CHECKPOINT_RESTOREoptions. PTRACE_DETACH- Restart the stopped tracee as for
PTRACE_CONT, but first detach from it. Under Linux, a tracee can be detached in this way regardless of which method was used to initiate tracing. (addr is ignored.) PTRACE_GET_THREAD_AREA(since Linux 2.6.0)- This operation performs a similar task to
get_thread_area(2). It reads the TLS entry in the GDT whose index is given in addr, placing a copy of the entry into the struct user_desc pointed to by data. (By contrast withget_thread_area(2), the entry_number of the struct user_desc is ignored.) PTRACE_SET_THREAD_AREA(since Linux 2.6.0)- This operation performs a similar task to
set_thread_area(2). It sets the TLS entry in the GDT whose index is given in addr, assigning it the data supplied in the struct user_desc pointed to by data. (By contrast withset_thread_area(2), the entry_number of the struct user_desc is ignored; in other words, this ptrace operation can’t be used to allocate a free TLS entry.) PTRACE_GET_SYSCALL_INFO(since Linux 5.3)- Retrieve information about the system call that caused the stop. The information is placed into the buffer pointed by the data argument, which should be a pointer to a buffer of type struct ptrace_syscall_info. The addr argument contains the size of the buffer pointed to by the data argument (i.e., sizeof(struct ptrace_syscall_info)). The return value contains the number of bytes available to be written by the kernel. If the size of the data to be written by the kernel exceeds the size specified by the addr argument, the output data is truncated.
- The ptrace_syscall_info structure contains the following fields:
- struct ptrace_syscal_info {
__u8 op; /* Type of system call stop */
__u32 arch; /* AUDIT_ARCH_* value; see seccomp(2) */
__u64 instruction_pointer; /* CPU instruction pointer */
__u64 stack_pointer; /* CPU stack pointer */
union {
struct { /* op == PTRACE_SYSCALL_INFO_ENTRY */
__u64 nr; /* System call number */
__u64 args[6]; /* System call arguments */
} entry;
struct { /* op == PTRACE_SYSCALL_INFO_EXIT */
__s64 rval; /* System call return value */
__u8 is_error; /* System call error flag;
Boolean: does rval contain
an error value (-ERRCODE) or
a nonerror return value? */
} exit;
struct { /* op == PTRACE_SYSCALL_INFO_SECCOMP */
__u64 nr; /* System call number */
