PTRACE(2) BSD Programmer's Manual PTRACE(2)NAMEptrace - debug user processes
SYNOPSIS
#include <sys/types.h>
#include <sys/ptrace.h>
int
ptrace(int request, pid_t pid, void *addr, int data);
DESCRIPTION
The ptrace() system call permits a parent process to manipulate the state
of a cooperative child process. It can read data from and write data to
the child's address space, alter the child's register and signal state,
stop and start the child at breakpoints, single-step the child or termi-
nate it. The parent may access the child only when it is stopped; the
parent can use wait(2) to detect a stopped child. When traced, the child
will stop when it receives any signal, so that the parent may examine the
signal and take appropriate action. The signal SIGTRAP is sent when the
child encounters a breakpoint. Debuggers use ptrace() and wait to start
and stop a child process at breakpoints.
The request parameter determines the type of access. When used, pid is
the process ID of the child, addr is the address or offset to be read or
written, and data is data to be written, or a signal to be sent. The re-
quests are as follows:
PT_TRACE_ME Register intent to be traced. A child process performs this
call to tell the system that its parent has permission to
trace it. It is usually made after a fork(2) and before an
execve(2). Only the request parameter is significant.
PT_CONTINUE Restart the child process with ID pid after it has stopped.
If addr has the value PT_ADDR_ANY, then the child continues
execution at the point of the previous program counter.
Otherwise, addr is the value of the new program counter. If
data is nonzero, it is treated as a signal number to be sent
to the child process just before it starts. A signal number
of zero indicates that no signal is to be sent.
PT_STEP Single-step the child process. PT_STEP is just like
PT_CONTINUE except that the child will stop with a SIGTRAP
after executing one instruction.
PT_KILL Terminate the child process with ID pid. The child behaves
just as though it had received a SIGKILL. The addr and data
parameters are ignored.
PT_READ_U Read system data, including register state, from the child
process with ID pid. The addr parameter is an offset into
system data for the child (see <sys/user.h>). One word of
data from the given aligned offset is returned as the value
of the ptrace() call. The data parameter is ignored.
PT_WRITE_U Write the given data into the system data area for the child
process with ID pid. The addr parameter is used as in
PT_READ_U but most system data is restricted from writing.
General register state may always be written, however.
PT_READ_I Read instructions from the child process with ID pid. The
addr parameter gives the location of the relevant data in
the child's address space. One word of data from the given
address is returned as the value of the ptrace() call.
PT_READ_D Read data from the child. On machines that distinguish in-
struction space from data space, this request fetches from
data space; otherwise it is identical to PT_READ_I.
PT_WRITE_I Write to the instruction space of the child process with ID
pid. This request is similar to PT_READ_I, except the value
of data is written to the given address. The parent may
write into locations that are read-only in the child. This
request is typically used to install breakpoint instruc-
tions, which generate SIGTRAP when executed.
PT_WRITE_D Write to data space in the child. This request works like
PT_WRITE_I for data space.
PT_ATTACH Attach to a process. The process with process ID pid be-
comes a child of the calling process, simulates a
PT_TRACE_ME operation, and is stopped as though it received
a SIGSTOP signal. The addr and data parameters are ignored.
The calling process may not attach to another given process
if the other process is:
o already traced
o the same as the calling process
o the init process (PID 1), except in insecure mode
o currently running with setuid or setgid privileges, or
has had them previously, unless the calling process has
superuser privileges
PT_DETACH Restore an attached process to its previous condition. This
request is very similar to PT_CONTINUE with the additional
features that:
o the given process is no longer traced
o the given process's original parent process is restored,
if that process is still alive
PT_EVENT If the current process is being traced, then the system will
send it a SIGTRAP signal. (If the SIGTRAP signal is cur-
rently blocked or ignored, it may not be delivered immedi-
ately or at all.) This request allows a process that is a
child of a debugger to notify the debugger that its state
has changed. The system saves the value of the addr parame-
ter for later use in core dumps, but the value is not inter-
preted. The pid and data parameters are ignored. Note that
if the current process is not being traced, the request is
ignored. This request always returns successfully.
Processes being traced are given some special handling in the kernel.
Any signal sent to a traced process will cause it to stop; the parent
gets to examine the signal and may or may not choose to deliver it. De-
buggers typically do not pass on a SIGTRAP that is due to a known break-
point or a single step, for example. If a traced process calls execve(2)
to read in a new executable file and run it, the system will ignore any
setuid or setgid bits in the file's mode. If the parent of a traced
child exits, the system sends a SIGKILL to the child. This prevents
traced children from being orphaned; since only the parent can restart a
stopped traced child, an unparented traced process would get stuck. Fi-
nally, a traced process which calls execve(2) is stopped automatically
after the first instruction executed in the new image so that a debugger
can insert breakpoints. Without this aid, a naive process might never
stop to let a debugger work on it.
RETURN VALUES
A -1 return value indicates that an error occurred and errno is set to
indicate the reason. Otherwise, if the request solicited data, then the
return value is the requested data; if the request doesn't solicit data,
the return value is zero.
ERRORSPtrace() will fail if any of the following occur:
[EIO] The request was not valid.
[EIO] An offset into system data for PT_READ_U or PT_WRITE_U is
out of range, unaligned or (for PT_WRITE_U) restricted
against writes.
[EIO] An invalid signal number for the child was given with
PT_CONTINUE or PT_STEP.
[ESRCH] For any request other than PT_TRACE_ME, the system could
not locate a process with ID pid.
[EPERM] The process with ID pid is not a child of the calling pro-
cess.
[EPERM] The child process has not arranged to be traced by request-
ing PT_TRACE_ME.
[EPERM] The calling process tried to set a process status bit in
the child process that is privileged.
[EPERM] The calling process tried to attach to the init process
(PID 1).
[EPERM] The calling process tried to attach to a setuid or setgid
process, and the calling process does not have superuser
privileges.
[EAGAIN] The child hasn't stopped yet.
[EAGAIN] The calling process tried to attach to a process that is
currently being traced.
[EINVAL] The address addr points outside the user part of the ad-
dress space.
[EINVAL] The calling process tried to attach to itself.
[ENOMEM] The address addr was invalid.
SEE ALSOwait(2)HISTORY
The ptrace function call appeared in Version 7 AT&T UNIX.
BUGS
The manipulation of registers by reading and writing an internal system
data structure is undocumented and grotesque. The system should provide
a completely different debugging interface that corrects both of these
problems.
BSDI BSD/OS December 15, 1997 3