minix/man/man2/ptrace.2
David van Moolenbroek b423d7b477 Merge of David's ptrace branch. Summary:
o Support for ptrace T_ATTACH/T_DETACH and T_SYSCALL
o PM signal handling logic should now work properly, even with debuggers
  being present
o Asynchronous PM/VFS protocol, full IPC support for senda(), and
  AMF_NOREPLY senda() flag

DETAILS

Process stop and delay call handling of PM:
o Added sys_runctl() kernel call with sys_stop() and sys_resume()
  aliases, for PM to stop and resume a process
o Added exception for sending/syscall-traced processes to sys_runctl(),
  and matching SIGKREADY pseudo-signal to PM
o Fixed PM signal logic to deal with requests from a process after
  stopping it (so-called "delay calls"), using the SIGKREADY facility
o Fixed various PM panics due to race conditions with delay calls versus
  VFS calls
o Removed special PRIO_STOP priority value
o Added SYS_LOCK RTS kernel flag, to stop an individual process from
  running while modifying its process structure

Signal and debugger handling in PM:
o Fixed debugger signals being dropped if a second signal arrives when
  the debugger has not retrieved the first one
o Fixed debugger signals being sent to the debugger more than once
o Fixed debugger signals unpausing process in VFS; removed PM_UNPAUSE_TR
  protocol message
o Detached debugger signals from general signal logic and from being
  blocked on VFS calls, meaning that even VFS can now be traced
o Fixed debugger being unable to receive more than one pending signal in
  one process stop
o Fixed signal delivery being delayed needlessly when multiple signals
  are pending
o Fixed wait test for tracer, which was returning for children that were
  not waited for
o Removed second parallel pending call from PM to VFS for any process
o Fixed process becoming runnable between exec() and debugger trap
o Added support for notifying the debugger before the parent when a
  debugged child exits
o Fixed debugger death causing child to remain stopped forever
o Fixed consistently incorrect use of _NSIG

Extensions to ptrace():
o Added T_ATTACH and T_DETACH ptrace request, to attach and detach a
  debugger to and from a process
o Added T_SYSCALL ptrace request, to trace system calls
o Added T_SETOPT ptrace request, to set trace options
o Added TO_TRACEFORK trace option, to attach automatically to children
  of a traced process
o Added TO_ALTEXEC trace option, to send SIGSTOP instead of SIGTRAP upon
  a successful exec() of the tracee
o Extended T_GETUSER ptrace support to allow retrieving a process's priv
  structure
o Removed T_STOP ptrace request again, as it does not help implementing
  debuggers properly
o Added MINIX3-specific ptrace test (test42)
o Added proper manual page for ptrace(2)

Asynchronous PM/VFS interface:
o Fixed asynchronous messages not being checked when receive() is called
  with an endpoint other than ANY
o Added AMF_NOREPLY senda() flag, preventing such messages from
  satisfying the receive part of a sendrec()
o Added asynsend3() that takes optional flags; asynsend() is now a
  #define passing in 0 as third parameter
o Made PM/VFS protocol asynchronous; reintroduced tell_fs()
o Made PM_BASE request/reply number range unique
o Hacked in a horrible temporary workaround into RS to deal with newly
  revealed RS-PM-VFS race condition triangle until VFS is asynchronous

System signal handling:
o Fixed shutdown logic of device drivers; removed old SIGKSTOP signal
o Removed is-superuser check from PM's do_procstat() (aka getsigset())
o Added sigset macros to allow system processes to deal with the full
  signal set, rather than just the POSIX subset

Miscellaneous PM fixes:
o Split do_getset into do_get and do_set, merging common code and making
  structure clearer
o Fixed setpriority() being able to put to sleep processes using an
  invalid parameter, or revive zombie processes
o Made find_proc() global; removed obsolete proc_from_pid()
o Cleanup here and there

Also included:
o Fixed false-positive boot order kernel warning
o Removed last traces of old NOTIFY_FROM code

THINGS OF POSSIBLE INTEREST

o It should now be possible to run PM at any priority, even lower than
  user processes
o No assumptions are made about communication speed between PM and VFS,
  although communication must be FIFO
o A debugger will now receive incoming debuggee signals at kill time
  only; the process may not yet be fully stopped
o A first step has been made towards making the SYSTEM task preemptible
2009-09-30 09:57:22 +00:00

184 lines
7.3 KiB
Groff

.TH PTRACE 2 "September 27, 2009"
.UC 4
.SH NAME
ptrace \- process trace
.SH SYNOPSIS
.nf
.ft B
#include <sys/types.h>
#include <sys/ptrace.h>
long ptrace(int \fIreq\fP, pid_t \fIpid\fP, long \fIaddr\fP, long \fIdata\fP)
.ft R
.fi
.SH DESCRIPTION
The \fBptrace\fP call provides a primitive means to trace (debug) another
process. A process can submit itself to tracing using a \fBT_OK\fP ptrace
request, or can be attached to by a tracer using a \fBT_ATTACH\fP request.
From that point on, whenever a signal is sent to the traced process,
the process will be stopped. Its tracer will be told about the signal
causing the stop, via
.BR wait (2).
The tracer can then inspect the traced process, and choose how to continue the
process's execution and whether to pass on the signal to it.
.PP
In the current model, the tracer will be notified of the signal before any
checks on ignore or block masks are made. A \fBSIGKILL\fP signal cannot be
intercepted by the tracer, and will always kill the traced process.
.PP
When the traced process performs a successful
.BR execve (2)
call, it will be stopped and a \fBSIGTRAP\fP will be generated for it.
Set-uid and set-gid bits on the new executable are ignored.
.PP
The \fIreq\fP parameter specifies the process trace request. The interpretation
of the remaining parameters depends on the given request. For all requests
except \fBT_OK\fP, the \fIpid\fP parameter specifies process ID of the target
process. For all requests except \fBT_OK\fP and \fBT_ATTACH\fP, the process
must be stopped. The following requests are supported:
.TP 2
.B T_OK
Set the caller's parent to be its tracer. All other arguments are ignored.
This request is typically made by the child fork of a debugger,
before performing an
.BR execve (2)
call.
.TP
.B T_GETINS, T_GETDATA
Retrieve a value from the given process's instruction and data area,
respectively, at the address given in \fIaddr\fP.
.TP
.B T_SETINS, T_SETDATA
Set the value from the given process's instruction and data area, respectively,
at the address given in \fIaddr\fP, to the value given in \fIdata\fP.
.TP
.B T_GETUSER
Retrieve the value at the zero-based offset given in \fIaddr\fP from the
process's \fBstruct proc\fP kernel structure, followed by, aligned on
\fBlong\fP size boundary, its \fBstruct priv\fP kernel structure.
.TP
.B T_SETUSER
Set some of the given process's registers at the beginning of its
\fBstruct proc\fP kernel structure. The value in \fIdata\fP will be written to
the zero-based offset given in \fIaddr\fP from the process's \fBstruct proc\fP
kernel structure.
.TP
.B T_RESUME
Resume execution of the process. A nonzero \fIdata\fP argument will be
interpreted as a signal to pass to the process.
.TP
.B T_STEP
Single-step an instruction. A nonzero \fIdata\fP argument will be interpreted
as a signal to pass to the process.
.TP
.B T_SYSCALL
Resume execution with system call tracing. When the traced process makes a
system call, a \fBSIGTRAP\fP signal will be generated. A subsequent
\fBT_SYSCALL\fP request will then cause a \fBSIGTRAP\fP signal to be generated
when the process leaves the system call. A nonzero \fIdata\fP argument will be
interpreted as a signal to pass to the process.
.TP
.B T_EXIT
Terminate the traced process, with the exit code given in the \fIdata\fP
argument. This call will return once the process has exited.
.TP
.B T_ATTACH
Attach to the given process. The process will be stopped with a \fBSIGSTOP\fP
signal.
.TP
.B T_DETACH
Detach from the given process. Any signals still pending for the tracer are
passed on directly to the process. A nonzero \fIdata\fP argument will be
interpreted as an additional signal to pass to the process.
.TP
.B T_SETOPT
Set the given process's trace options to the bit combination of flags given
in the \fIdata\fP argument.
.PP
The following option flags are currently supported for \fBT_SETOPT\fP:
.TP 2
.B TO_TRACEFORK
When the traced process performs a
.BR fork (2),
automatically attach to the new child as well.
The child will be stopped with a \fBSIGSTOP\fP signal right after forking.
.TP
.B TO_ALTEXEC
Send \fBSIGSTOP\fP instead of \fBSIGTRAP\fP upon a successful
.BR execve (2).
This allows the tracer to disambiguate between this case and other traps.
.PP
All addresses specified for the \fBT_GET\fP* and \fBT_SET\fP* requests must be
aligned on \fBlong\fP boundary. Similarly, only \fBlong\fP sized values can be
retrieved and set at a time.
.SH "RETURN VALUE"
All but the \fBT_GET\fP* requests return 0 upon successful completion.
Otherwise, a value of -1 is returned and \fIerrno\fP is set to indicate the
error.
.PP
The \fBT_GET\fP* requests return the resulting data. Here, -1 is a legitimate
return value. To distinguish between this and an error, clear \fIerrno\fP
before the \fBptrace\fP call, and check whether it is zero afterwards.
.SH ERRORS
The functions will fail if any of the following errors occur:
.TP 10
.B EINVAL
Invalid request or signal given.
.TP 10
.B ESRCH
The given process is not found, exiting, or not traced by the caller.
.TP 10
.B EBUSY
The given process is not stopped, or already being traced.
.TP 10
.B EIO
The given address is out of range or not properly aligned.
.TP 10
.B EPERM
Attaching is denied, because the caller equals the given process,
or the caller is not root and does not match the given process's
user or group ID, or the caller is not root and the given process
is a system process, or the caller is a system process,
or the given process may not be traced at all.
.TP
.SH LIMITATIONS
Signals are not ordered. Attaching to a process guarantees that a \fBSIGSTOP\fP
will arrive at the tracer, but it is not guaranteed that this will be the first
signal to arrive. The same goes for automatically attached children of the
traced process. Similarly, if the tracer wants to detach from a running
process, it will typically send a \fBSIGSTOP\fP using
.BR kill (2)
to the process to stop it, but there is no guarantee that this will be the
first signal to arrive.
.PP
Signals not caused by the process itself (e.g. those caused by
.BR kill (2))
will arrive at the tracer while the process is in stopped state, but this does
not imply that the process is in a stable state at that point. The process may
still have a system call pending, and this means that registers and memory of
the process may change almost arbitrarily after the tracer has been told about
the arrival of the current signal. Implementers of debuggers are advised to
make minimal assumptions about the conditions of the process when an unexpected
signal arrives.
.PP
It is not possible to use \fBT_SYSCALL\fP to get a trap upon leaving of a
system call, if \fBT_SYSCALL\fP was not used to get a trap upon entering that
system call. This is in fact helpful: after attaching to a process, the first
\fBT_SYSCALL\fP call will always cause a trap after entering the next system
call. As the only exception, \fBT_SYSCALL\fP on a
.BR fork (2)
call of a process with \fBTO_TRACEFORK\fP set, will result in two traps upon
leaving: one for the parent, and one for the child. The child's \fBSIGSTOP\fP
signal will always come before the \fBSIGTRAP\fP from its leaving the system
call.
.PP
There is no way to reliably distinguish between real signals and signals
generated for the tracer.
.PP
For system stability reasons, the PM and VM servers cannot be traced.
.SH "SEE ALSO"
.BR wait (2),
.BR kill (2),
.BR mdb (1)
.SH AUTHOR
Manual page written by David van Moolenbroek <dcvmoole@cs.vu.nl>