PTRACE(2)

NAME
ptrace - process trace

SYNOPSIS
#include <signal.h>
#include <machine/ptrace.h>

ptrace(request, pid, addr, data)
int request, pid, *addr, data;

DESCRIPTION
Ptrace provides a means by which a parent process may control the execution of a child process, and examine and change its core image. Its primary use is for the implementation of breakpoint debugging. There are four arguments whose interpretation depends on a request argument. Generally, pid is the process ID of the traced process, which must be a child (no more distant descendant) of the tracing process. A process being traced behaves normally until it encounters some signal whether internally generated like “illegal instruction” or externally generated like “interrupt”. See sigvec(2) for the list. Then the traced process enters a stopped state and its parent is notified via wait(2). When the child is in the stopped state, its core image can be examined and modified using ptrace. If desired, another ptrace request can then cause the child either to terminate or to continue, possibly ignoring the signal.

The value of the request argument determines the precise action of the call:

PT_CHILD
    This request is the only one used by the child process; it declares that the process is to be traced by its parent. All the other arguments are ignored. Peculiar results will ensue if the parent does not expect to trace the child. The child process requesting to be traced must execve(2) an image before ptrace requests generated by the parent process are effective.

PT_RTEXT, PT_RDATA
    The word in the child process's address space at addr is returned. If I and D space are separated (e.g. historically on a pdp-11), request 1 indicates I space, 2 D space. Addr must be even. The child must be stopped. The input data is ignored.

PT_RUSER
    The word of the system's per-process data area corresponding to addr is returned. Addr must be even and less than 4096. This space contains the registers and other information about the process; its layout corresponds to the user structure in the system.

PT_WTEXT, PT_WDATA
    The given data is written at the word in the process's address space corresponding to addr, which must be even. No useful value is returned. If I and D space are separated, request 4 indicates I space, 5 D space. Attempts to write in pure procedure fail if another process is executing the same file.

PT_WUSER
    The process's system data is written, as it is read with request 3. Only a few locations can be written in this way: the general registers, the floating point status and registers, and certain bits of the processor status word.

PT_CONTSIG
    The data argument is taken as a signal number and the child's execution continues at location addr as if it had incurred that signal. Normally the signal number will be either 0 to indicate that the signal that caused the stop should be ignored, or that value fetched out of the process's image indicating which signal caused the stop. If addr is (int *)1 then execution continues from where it stopped.

PT_KILL
    The traced process terminates.

PT_SSTEP
    Execution continues as in request 7; however, as soon as possible after execution of at least one instruction, execution stops again. The signal number from the stop is SIGTRAP. This is part of the mechanism for implementing breakpoints.

Unlike a single process debugger all decendants of the process declared as a multi-process debugger are traced and do not require themselves to use PT_CHILD as in ptrace(2).

XPT_DEBUGGER
    A process uses this request to declare itself a multi-process debugger. All other arguments are ignored. All subsequent forks, execs, and exits, as well as signals of all children of the calling process, their descendants, and selected other processes (see XPT_DEBUG), notify the debugger with SIGCHLD.

XPT_SETSIGMASK
    The data parameter points to a mask of signals in the selected process. Signals so set are passed directly to the selected process, rather than notifying the debugger and stopping the process. This mask is inherited across forks of the process, and kept when the process exec's. A passed-through signal is a process attribute; it is passed through regardless of how many debuggers are controlling the process.

XPT_RREGS, XPT_WREGS
    The selected process's register set is read or written. addr points to a pt_regset structure (see ptrace.h). Machine specific restrictions usually apply; for example, typically only a few of the processor-status register bits are actually written.

XPT_RPROC
    The selected process's process table entry is placed at *addr. See <sys/proc.h> for definition of struct proc.

XPT_SIGNAL
    The data argument is a signal number that is sent to process selected by pid. If pid==0, the signal is sent to all processes under control of the debugger.

XPT_STOPSTAT
    Information about a stopped process is returned. The pid argument is ignored. A debugged process stops whenever it forks, execs, exits, hits a watchpoint, or is about to process a signal, and sends the debugger a SIGCHLD. addr points at a pt_stop structure, which receives the pid and reason for the stop. If the reason was because of a watchpoint hit, it also contains the number of the watchpoint. If no controlled process is stopped that has not yet been reported by XPT_STOPSTAT, an ESRCH error is returned.

XPT_DUPFD
    The open file descriptor in the caller given by data is dup'd (see dup(2)) into pid's file-descriptor named by addr. If pid already has an open file-descriptor there it is closed. This is an experimental interface.

The following functions are not supported in the first implementation:

XPT_DEBUG
    The process tree rooted at pid becomes controlled by the debugger. pid must not be an ancestor of the debugger or already under debug. The caller must be root or match the effective uid of all processes in the selected process tree. No process in the tree can be running a set-user or set-group process.

XPT_OPENT
    ptrace returns an open, read-only file descriptor for the binary file being executed by pid. The debugger must have read-access to the file for this to succeed. This allows the debugger to access the symbol table without having to know the name of the executable file.

XPT_WATCHPT_SET
    An instruction or data watchpoint is set for the selected process. addr points to a pt_watchpt structure which specifies the address, type, length, and number of the watchpoint.

XPT_WATCHPT_CLEAR
    The specified watchpoint is cleared for the selected process. addr points to a pt_watchpt structure which contains the number of the watchpoint to be cleared. Other fields in the watchpt structure are ignored.

As indicated, these calls (except for request PT_CHILD) can be used only when the subject process has stopped. The wait call is used to determine when a process stops; in such a case the “termination” status returned by wait has the value 0177 to indicate stoppage rather than genuine termination.

To forestall possible fraud, ptrace inhibits the set-user-id and set-group-id facilities on subsequent execve(2) calls. If a traced process calls execve, it will stop before executing the first instruction of the new image showing signal SIGTRAP.

On the BALANCE Series, “word” also means a 32-bit integer, but the “even” restriction does not apply.

RETURN VALUE
A 0 value is returned if the call succeeds. If the call fails then a -1 is returned and the global variable errno is set to indicate the error.

ERRORS

[EBADF]
    The data or addr argument specifies a bad file descriptor number for XPT_DUPFD.

[EIO]
    The request code is invalid.

[ESRCH]
    The specified process does not exist.

[ESRCH]
    The child is not stopped.

[ESRCH]
    The process requested itself to be traced and it is a child of init(8) (process 1).

[ESRCH]
    The process to be traced is not the child of the current process.

[ESRCH]
    The child process has not requested to be traced.

[EIO]
    The given signal number is invalid.

[EIO]
    The specified address is out of bounds.

[EPERM]
    The specified process cannot be traced.

[EIO]
    The child cannot perform the task requested.

SEE ALSO
ddt(1), sigvec(2), wait(2)

BUGS
Ptrace is unique and arcane; it should be replaced with a special file which can be opened and read and written. The control functions could then be implemented with ioctl(2) calls on this file. This would be simpler to understand and have much higher performance.

The request 0 call should be able to specify signals which are to be treated normally and not cause a stop. In this way, for example, programs with simulated floating point (which use “illegal instruction” signals at a very high rate) could be efficiently debugged.

The error indication, -1, is a legitimate function value; errno, see intro(2), can be used to disambiguate.

It should be possible to stop a process on occurrence of a system call; in this way a completely controlled environment could be provided.