2004-11-03 13:51:07 +00:00
|
|
|
.\" Hey Emacs! This file is -*- nroff -*- source.
|
|
|
|
.\"
|
|
|
|
.\" Copyright (c) 1993 Michael Haardt
|
|
|
|
.\" (michael@moria.de),
|
|
|
|
.\" Fri Apr 2 11:32:09 MET DST 1993
|
|
|
|
.\"
|
|
|
|
.\" changes Copyright 1999 Mike Coleman (mkc@acm.org)
|
|
|
|
.\" -- major revision to fully document ptrace semantics per recent Linux
|
2007-04-12 22:42:49 +00:00
|
|
|
.\" kernel (2.2.10) and glibc (2.1.2)
|
2004-11-03 13:51:07 +00:00
|
|
|
.\" Sun Nov 7 03:18:35 CST 1999
|
|
|
|
.\"
|
|
|
|
.\" This is free documentation; you can redistribute it and/or
|
|
|
|
.\" modify it under the terms of the GNU General Public License as
|
|
|
|
.\" published by the Free Software Foundation; either version 2 of
|
|
|
|
.\" the License, or (at your option) any later version.
|
|
|
|
.\"
|
|
|
|
.\" The GNU General Public License's references to "object code"
|
|
|
|
.\" and "executables" are to be interpreted as the output of any
|
|
|
|
.\" document formatting or typesetting system, including
|
|
|
|
.\" intermediate and printed output.
|
|
|
|
.\"
|
|
|
|
.\" This manual is distributed in the hope that it will be useful,
|
|
|
|
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
.\" GNU General Public License for more details.
|
|
|
|
.\"
|
|
|
|
.\" You should have received a copy of the GNU General Public
|
|
|
|
.\" License along with this manual; if not, write to the Free
|
|
|
|
.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
|
|
|
|
.\" USA.
|
|
|
|
.\"
|
|
|
|
.\" Modified Fri Jul 23 23:47:18 1993 by Rik Faith <faith@cs.unc.edu>
|
|
|
|
.\" Modified Fri Jan 31 16:46:30 1997 by Eric S. Raymond <esr@thyrsus.com>
|
|
|
|
.\" Modified Thu Oct 7 17:28:49 1999 by Andries Brouwer <aeb@cwi.nl>
|
2007-09-20 06:52:22 +00:00
|
|
|
.\" Modified, 27 May 2004, Michael Kerrisk <mtk.manpages@gmail.com>
|
2004-11-03 13:51:07 +00:00
|
|
|
.\" Added notes on capability requirements
|
|
|
|
.\"
|
2006-03-23 22:00:08 +00:00
|
|
|
.\" 2006-03-24, Chuck Ebbert <76306.1226@compuserve.com>
|
|
|
|
.\" Added PTRACE_SETOPTIONS, PTRACE_GETEVENTMSG, PTRACE_GETSIGINFO,
|
|
|
|
.\" PTRACE_SETSIGINFO, PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP
|
|
|
|
.\" (Thanks to Blaisorblade, Daniel Jacobowitz and others who helped.)
|
|
|
|
.\"
|
2011-09-07 17:40:09 +00:00
|
|
|
.\" FIXME: Linux 3.1 adds PTRACE_SEIZE, PTRACE_INTERRUPT, and PTRACE_LISTEN.
|
|
|
|
.\"
|
2009-03-29 20:30:23 +00:00
|
|
|
.TH PTRACE 2 2009-03-30 "Linux" "Linux Programmer's Manual"
|
2004-11-03 13:51:07 +00:00
|
|
|
.SH NAME
|
|
|
|
ptrace \- process trace
|
|
|
|
.SH SYNOPSIS
|
2006-03-23 22:00:08 +00:00
|
|
|
.nf
|
2004-11-03 13:51:07 +00:00
|
|
|
.B #include <sys/ptrace.h>
|
|
|
|
.sp
|
2006-03-23 22:00:08 +00:00
|
|
|
.BI "long ptrace(enum __ptrace_request " request ", pid_t " pid ", "
|
|
|
|
.BI " void *" addr ", void *" data );
|
|
|
|
.fi
|
2004-11-03 13:51:07 +00:00
|
|
|
.SH DESCRIPTION
|
|
|
|
The
|
2005-10-19 06:54:38 +00:00
|
|
|
.BR ptrace ()
|
2011-09-24 06:29:34 +00:00
|
|
|
system call provides a means by which a process (tracer) may observe
|
|
|
|
and control the execution of another processes (tracees),
|
|
|
|
and examine and change their core image and registers.
|
2006-03-25 21:28:28 +00:00
|
|
|
It is primarily used to implement breakpoint debugging and system
|
2004-11-03 13:51:07 +00:00
|
|
|
call tracing.
|
|
|
|
.LP
|
2011-09-24 06:29:34 +00:00
|
|
|
Tracees first need to be attached to the tracer.
|
|
|
|
Attachment and subsequent commands are per-thread: in
|
|
|
|
multi-threaded 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 multi-threaded) process". Ptrace commands are always sent to
|
|
|
|
a specific tracee using ptrace(PTRACE_foo, pid, ...), where pid is the
|
|
|
|
thread ID of the corresponding Linux thread.
|
|
|
|
.LP
|
|
|
|
The process can initiate a trace by calling
|
2007-04-12 22:42:49 +00:00
|
|
|
.BR fork (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
and having the resulting child do a
|
|
|
|
.BR PTRACE_TRACEME ,
|
2006-03-25 21:28:28 +00:00
|
|
|
followed (typically) by an
|
2011-09-24 06:29:34 +00:00
|
|
|
.BR execve (2).
|
|
|
|
Alternatively, the process may commence trace of an existing process using
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_ATTACH .
|
2004-11-03 13:51:07 +00:00
|
|
|
.LP
|
2011-09-24 06:29:34 +00:00
|
|
|
While being traced, the tracee will stop each time a signal is delivered,
|
2007-04-12 22:42:49 +00:00
|
|
|
even if the signal is being ignored.
|
2007-06-21 05:38:48 +00:00
|
|
|
(The exception is
|
|
|
|
.BR SIGKILL ,
|
|
|
|
which has its usual effect.)
|
2011-09-24 06:29:34 +00:00
|
|
|
The tracer will be notified at its next
|
2004-11-03 13:51:07 +00:00
|
|
|
.BR wait (2)
|
2011-09-24 06:29:34 +00:00
|
|
|
and may inspect and modify the tracee while it is stopped.
|
|
|
|
The tracer then causes the tracee to continue,
|
2006-03-25 21:28:28 +00:00
|
|
|
optionally ignoring the delivered signal
|
2004-11-03 13:51:07 +00:00
|
|
|
(or even delivering a different signal instead).
|
|
|
|
.LP
|
2011-09-24 06:29:34 +00:00
|
|
|
When the tracer is finished tracing, it can cause tracee to continue
|
|
|
|
executing in a normal, untraced mode via
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_DETACH .
|
2004-11-03 13:51:07 +00:00
|
|
|
.LP
|
|
|
|
The value of \fIrequest\fP determines the action to be performed:
|
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.B PTRACE_TRACEME
|
2007-04-12 22:42:49 +00:00
|
|
|
Indicates that this process is to be traced by its parent.
|
2011-09-24 06:29:34 +00:00
|
|
|
Any signal (except
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR SIGKILL )
|
|
|
|
delivered to this process will cause it to stop and its
|
2004-11-03 13:51:07 +00:00
|
|
|
parent to be notified via
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR wait (2).
|
2004-11-03 13:51:07 +00:00
|
|
|
Also, all subsequent calls to
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR execve (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
by this process will cause a
|
|
|
|
.B SIGTRAP
|
|
|
|
to be sent to it,
|
2007-04-12 22:42:49 +00:00
|
|
|
giving the parent a chance to gain control before the new program
|
|
|
|
begins execution.
|
|
|
|
A process probably shouldn't make this request if its parent
|
|
|
|
isn't expecting to trace it.
|
2006-03-25 21:28:28 +00:00
|
|
|
(\fIpid\fP, \fIaddr\fP, and \fIdata\fP are ignored.)
|
2004-11-03 13:51:07 +00:00
|
|
|
.LP
|
2011-09-24 06:29:34 +00:00
|
|
|
The above request is used only by the tracee;
|
|
|
|
the rest are used only by the tracer.
|
|
|
|
In the following requests, \fIpid\fP specifies the tracee
|
2007-04-12 22:42:49 +00:00
|
|
|
to be acted on.
|
2007-06-21 05:38:48 +00:00
|
|
|
For requests other than
|
|
|
|
.BR PTRACE_KILL ,
|
2011-09-24 06:29:34 +00:00
|
|
|
the tracee must be stopped.
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_PEEKTEXT ", " PTRACE_PEEKDATA
|
2004-11-03 13:51:07 +00:00
|
|
|
Reads a word at the location
|
2007-09-20 16:26:31 +00:00
|
|
|
.I addr
|
2011-09-24 06:29:34 +00:00
|
|
|
in the tracee's memory, returning the word as the result of the
|
2005-10-19 06:54:38 +00:00
|
|
|
.BR ptrace ()
|
2007-04-12 22:42:49 +00:00
|
|
|
call.
|
2006-03-25 21:28:28 +00:00
|
|
|
Linux does not have separate text and data address spaces, so the two
|
2007-04-12 22:42:49 +00:00
|
|
|
requests are currently equivalent.
|
2006-03-25 21:28:28 +00:00
|
|
|
(The argument \fIdata\fP is ignored.)
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-10-17 20:49:47 +00:00
|
|
|
.B PTRACE_PEEKUSER
|
2007-11-24 07:34:48 +00:00
|
|
|
.\" PTRACE_PEEKUSR in kernel source, but glibc uses PTRACE_PEEKUSER,
|
|
|
|
.\" and that is the name that seems common on other systems.
|
2004-11-03 13:51:07 +00:00
|
|
|
Reads a word at offset
|
|
|
|
.I addr
|
2011-09-24 06:29:34 +00:00
|
|
|
in the tracee's USER area,
|
2007-06-21 05:38:48 +00:00
|
|
|
which holds the registers and other information about the process
|
2009-03-29 20:30:23 +00:00
|
|
|
(see \fI<sys/user.h>\fP).
|
2006-03-25 21:28:28 +00:00
|
|
|
The word is returned as the result of the
|
2005-10-19 06:54:38 +00:00
|
|
|
.BR ptrace ()
|
2007-04-12 22:42:49 +00:00
|
|
|
call.
|
2006-03-25 21:28:28 +00:00
|
|
|
Typically the offset must be word-aligned, though this might vary by
|
2008-05-21 20:23:25 +00:00
|
|
|
architecture.
|
|
|
|
See NOTES.
|
|
|
|
(\fIdata\fP is ignored.)
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_POKETEXT ", " PTRACE_POKEDATA
|
2004-11-03 13:51:07 +00:00
|
|
|
Copies the word
|
2007-09-20 16:26:31 +00:00
|
|
|
.I data
|
2004-11-03 13:51:07 +00:00
|
|
|
to location
|
2007-09-20 16:26:31 +00:00
|
|
|
.I addr
|
2011-09-24 06:29:34 +00:00
|
|
|
in the tracee's memory.
|
2007-04-12 22:42:49 +00:00
|
|
|
As above, the two requests are currently equivalent.
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-10-17 20:49:47 +00:00
|
|
|
.B PTRACE_POKEUSER
|
2007-11-24 07:34:48 +00:00
|
|
|
.\" PTRACE_POKEUSR in kernel source, but glibc uses PTRACE_POKEUSER,
|
|
|
|
.\" and that is the name that seems common on other systems.
|
2004-11-03 13:51:07 +00:00
|
|
|
Copies the word
|
2007-09-20 16:26:31 +00:00
|
|
|
.I data
|
2004-11-03 13:51:07 +00:00
|
|
|
to offset
|
|
|
|
.I addr
|
2011-09-24 06:29:34 +00:00
|
|
|
in the tracee's USER area.
|
2007-04-12 22:42:49 +00:00
|
|
|
As above, the offset must typically be word-aligned.
|
|
|
|
In order to maintain the integrity of the kernel,
|
2007-06-21 05:38:48 +00:00
|
|
|
some modifications to the USER area are disallowed.
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_GETREGS ", " PTRACE_GETFPREGS
|
2011-09-24 06:29:34 +00:00
|
|
|
Copies the tracee's general purpose or floating-point registers,
|
|
|
|
respectively, to location \fIdata\fP in the tracer.
|
2009-03-29 20:30:23 +00:00
|
|
|
See \fI<sys/user.h>\fP for information on
|
2008-09-10 03:45:09 +00:00
|
|
|
the format of this data.
|
|
|
|
(\fIaddr\fP is ignored.)
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_GETSIGINFO " (since Linux 2.3.99-pre6)"
|
2006-03-23 22:00:08 +00:00
|
|
|
Retrieve information about the signal that caused the stop.
|
|
|
|
Copies a \fIsiginfo_t\fP structure (see
|
|
|
|
.BR sigaction (2))
|
2011-09-24 06:29:34 +00:00
|
|
|
from the tracee to location \fIdata\fP in the tracer.
|
2006-03-23 22:00:08 +00:00
|
|
|
(\fIaddr\fP is ignored.)
|
|
|
|
.TP
|
2007-10-16 19:18:17 +00:00
|
|
|
.BR PTRACE_SETREGS ", " PTRACE_SETFPREGS
|
2011-09-24 06:29:34 +00:00
|
|
|
Copies the tracee's general purpose or floating-point registers,
|
|
|
|
respectively, from location \fIdata\fP in the tracer.
|
2007-06-21 05:38:48 +00:00
|
|
|
As for
|
|
|
|
.BR PTRACE_POKEUSER ,
|
|
|
|
some general
|
2007-04-12 22:42:49 +00:00
|
|
|
purpose register modifications may be disallowed.
|
2006-03-25 21:28:28 +00:00
|
|
|
(\fIaddr\fP is ignored.)
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_SETSIGINFO " (since Linux 2.3.99-pre6)"
|
2006-03-23 22:00:08 +00:00
|
|
|
Set signal information.
|
2007-04-12 22:42:49 +00:00
|
|
|
Copies a \fIsiginfo_t\fP structure from location \fIdata\fP in the
|
2011-09-24 06:29:34 +00:00
|
|
|
tracer to the tracee.
|
2006-03-23 22:00:08 +00:00
|
|
|
This will only affect signals that would normally be delivered to
|
2011-09-24 06:29:34 +00:00
|
|
|
the tracee and were caught by the tracer.
|
2007-04-12 22:42:49 +00:00
|
|
|
It may be difficult to tell
|
2006-03-23 22:00:08 +00:00
|
|
|
these normal signals from synthetic signals generated by
|
|
|
|
.BR ptrace ()
|
2008-05-21 20:23:25 +00:00
|
|
|
itself.
|
|
|
|
(\fIaddr\fP is ignored.)
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_SETOPTIONS " (since Linux 2.4.6; see BUGS for caveats)"
|
2011-09-24 06:29:34 +00:00
|
|
|
Sets ptrace options from \fIdata\fP.
|
2006-03-23 22:00:08 +00:00
|
|
|
(\fIaddr\fP is ignored.)
|
|
|
|
\fIdata\fP is interpreted
|
2007-07-01 04:23:34 +00:00
|
|
|
as a bit mask of options, which are specified by the following flags:
|
2006-03-23 22:00:08 +00:00
|
|
|
.RS
|
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_O_TRACESYSGOOD " (since Linux 2.4.6)"
|
2007-04-12 22:42:49 +00:00
|
|
|
When delivering syscall traps, set bit 7 in the signal number
|
2011-09-18 21:41:17 +00:00
|
|
|
(i.e., deliver \fISIGTRAP | 0x80\fP).
|
2006-03-25 21:28:28 +00:00
|
|
|
This makes it easy for the tracer to tell the difference
|
2007-04-12 22:42:49 +00:00
|
|
|
between normal traps and those caused by a syscall.
|
2007-06-21 05:38:48 +00:00
|
|
|
.RB ( PTRACE_O_TRACESYSGOOD
|
|
|
|
may not work on all architectures.)
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_O_TRACEFORK " (since Linux 2.5.46)"
|
2011-09-24 06:29:34 +00:00
|
|
|
Stop the tracee at the next
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR fork (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
call with \fISIGTRAP | PTRACE_EVENT_FORK\ <<\ 8\fP and automatically
|
2007-04-12 22:42:49 +00:00
|
|
|
start tracing the newly forked process,
|
2007-06-21 05:38:48 +00:00
|
|
|
which will start with a
|
|
|
|
.BR SIGSTOP .
|
|
|
|
The PID for the new process can be retrieved with
|
|
|
|
.BR PTRACE_GETEVENTMSG .
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_O_TRACEVFORK " (since Linux 2.5.46)"
|
2011-09-24 06:29:34 +00:00
|
|
|
Stop the tracee at the next
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR vfork (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
call with \fISIGTRAP | PTRACE_EVENT_VFORK\ <<\ 8\fP and automatically start
|
|
|
|
tracing the newly vforked process, which will start with a
|
|
|
|
.BR SIGSTOP .
|
|
|
|
The PID for the new process can be retrieved with
|
|
|
|
.BR PTRACE_GETEVENTMSG .
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_O_TRACECLONE " (since Linux 2.5.46)"
|
2011-09-24 06:29:34 +00:00
|
|
|
Stop the tracee at the next
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR clone (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
call with \fISIGTRAP | PTRACE_EVENT_CLONE\ <<\ 8\fP and automatically start
|
|
|
|
tracing the newly cloned process, which will start with a
|
|
|
|
.BR SIGSTOP .
|
|
|
|
The PID for the new process can be retrieved with
|
|
|
|
.BR PTRACE_GETEVENTMSG .
|
2006-03-23 22:00:08 +00:00
|
|
|
This option may not catch
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR clone (2)
|
2007-04-12 22:42:49 +00:00
|
|
|
calls in all cases.
|
2011-09-24 06:29:34 +00:00
|
|
|
If the tracee calls
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR clone (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
with the
|
2007-09-20 16:26:31 +00:00
|
|
|
.B CLONE_VFORK
|
2007-06-21 05:38:48 +00:00
|
|
|
flag,
|
|
|
|
.B PTRACE_EVENT_VFORK
|
|
|
|
will be delivered instead
|
|
|
|
if
|
|
|
|
.B PTRACE_O_TRACEVFORK
|
2011-09-24 06:29:34 +00:00
|
|
|
is set; otherwise if the tracee calls
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR clone (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
with the exit signal set to
|
|
|
|
.BR SIGCHLD ,
|
|
|
|
.B PTRACE_EVENT_FORK
|
|
|
|
will be delivered
|
|
|
|
if
|
|
|
|
.B PTRACE_O_TRACEFORK
|
|
|
|
is set.
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_O_TRACEEXEC " (since Linux 2.5.46)"
|
2011-09-24 06:29:34 +00:00
|
|
|
Stop the tracee at the next
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR execve (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
call with \fISIGTRAP | PTRACE_EVENT_EXEC\ <<\ 8\fP.
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_O_TRACEVFORKDONE " (since Linux 2.5.60)"
|
2011-09-24 06:29:34 +00:00
|
|
|
Stop the tracee at the completion of the next
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR vfork (2)
|
2007-06-21 05:38:48 +00:00
|
|
|
call with \fISIGTRAP | PTRACE_EVENT_VFORK_DONE\ <<\ 8\fP.
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_O_TRACEEXIT " (since Linux 2.5.60)"
|
2011-09-24 06:29:34 +00:00
|
|
|
Stop the tracee at exit with \fISIGTRAP | PTRACE_EVENT_EXIT\ <<\ 8\fP.
|
|
|
|
The tracee's exit status can be retrieved with
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_GETEVENTMSG .
|
2007-04-12 22:42:49 +00:00
|
|
|
This stop will be done 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
|
2006-03-25 21:28:28 +00:00
|
|
|
is finished exiting.
|
2006-03-23 22:00:08 +00:00
|
|
|
Even though context is available, the tracer cannot prevent the exit from
|
|
|
|
happening at this point.
|
|
|
|
.RE
|
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_GETEVENTMSG " (since Linux 2.5.46)"
|
2007-04-12 22:42:49 +00:00
|
|
|
Retrieve a message (as an
|
|
|
|
.IR "unsigned long" )
|
2006-03-23 22:00:08 +00:00
|
|
|
about the ptrace event
|
2011-09-24 06:29:34 +00:00
|
|
|
that just happened, placing it in the location \fIdata\fP in the tracer.
|
2007-06-21 05:38:48 +00:00
|
|
|
For
|
2007-09-20 16:26:31 +00:00
|
|
|
.B PTRACE_EVENT_EXIT
|
2011-09-24 06:29:34 +00:00
|
|
|
this is the tracee's exit status.
|
2007-06-21 05:38:48 +00:00
|
|
|
For
|
|
|
|
.BR PTRACE_EVENT_FORK ,
|
2007-09-20 16:26:31 +00:00
|
|
|
.B PTRACE_EVENT_VFORK
|
2007-06-21 05:38:48 +00:00
|
|
|
and
|
|
|
|
.B PTRACE_EVENT_CLONE
|
|
|
|
this
|
2007-04-12 22:42:49 +00:00
|
|
|
is the PID of the new process.
|
2006-11-25 01:21:51 +00:00
|
|
|
Since Linux 2.6.18, the PID of the new process is also available
|
2007-06-21 05:38:48 +00:00
|
|
|
for
|
|
|
|
.BR PTRACE_EVENT_VFORK_DONE .
|
2006-11-25 01:21:51 +00:00
|
|
|
(\fIaddr\fP is ignored.)
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.B PTRACE_CONT
|
2011-09-24 06:29:34 +00:00
|
|
|
Restarts the stopped tracee process.
|
|
|
|
If \fIdata\fP is nonzero, it is interpreted as a signal to be delivered to the tracee;
|
2007-04-12 22:42:49 +00:00
|
|
|
otherwise, no signal is delivered.
|
2011-09-24 06:29:34 +00:00
|
|
|
Thus, for example, the tracer can control
|
|
|
|
whether a signal sent to the tracee is delivered or not.
|
2006-03-25 21:28:28 +00:00
|
|
|
(\fIaddr\fP is ignored.)
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_SYSCALL ", " PTRACE_SINGLESTEP
|
2011-09-24 06:29:34 +00:00
|
|
|
Restarts the stopped tracee as for
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_CONT ,
|
|
|
|
but arranges for
|
2011-09-24 06:29:34 +00:00
|
|
|
the tracee to be stopped at the next entry to or exit from a system call,
|
2007-04-12 22:42:49 +00:00
|
|
|
or after execution of a single instruction, respectively.
|
2011-09-24 06:29:34 +00:00
|
|
|
(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
|
2007-06-21 05:38:48 +00:00
|
|
|
stopped by receipt of a
|
|
|
|
.BR SIGTRAP .
|
|
|
|
So, for
|
|
|
|
.BR PTRACE_SYSCALL ,
|
|
|
|
for example, the idea is to inspect
|
2007-04-12 22:42:49 +00:00
|
|
|
the arguments to the system call at the first stop,
|
2007-06-21 05:38:48 +00:00
|
|
|
then do another
|
|
|
|
.B PTRACE_SYSCALL
|
|
|
|
and inspect the return value of
|
2007-04-12 22:42:49 +00:00
|
|
|
the system call at the second stop.
|
2009-03-30 00:30:07 +00:00
|
|
|
The
|
|
|
|
.I data
|
|
|
|
argument is treated as for
|
|
|
|
.BR PTRACE_CONT .
|
2006-03-25 21:28:28 +00:00
|
|
|
(\fIaddr\fP is ignored.)
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-10-16 19:18:17 +00:00
|
|
|
.BR PTRACE_SYSEMU ", " PTRACE_SYSEMU_SINGLESTEP " (since Linux 2.6.14)"
|
2007-06-21 05:38:48 +00:00
|
|
|
For
|
|
|
|
.BR PTRACE_SYSEMU ,
|
|
|
|
continue and stop on entry to the next syscall,
|
2007-04-12 22:42:49 +00:00
|
|
|
which will not be executed.
|
2007-06-21 05:38:48 +00:00
|
|
|
For
|
|
|
|
.BR PTRACE_SYSEMU_SINGLESTEP ,
|
|
|
|
do the same
|
2007-04-12 22:42:49 +00:00
|
|
|
but also singlestep if not a syscall.
|
|
|
|
This call is used by programs like
|
2011-09-24 06:29:34 +00:00
|
|
|
User Mode Linux that want to emulate all the tracee's system calls.
|
2009-03-30 00:30:07 +00:00
|
|
|
The
|
|
|
|
.I data
|
|
|
|
argument is treated as for
|
|
|
|
.BR PTRACE_CONT .
|
|
|
|
(\fIaddr\fP is ignored;
|
2006-03-25 21:28:28 +00:00
|
|
|
not supported on all architectures.)
|
2006-03-23 22:00:08 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.B PTRACE_KILL
|
2011-09-24 06:29:34 +00:00
|
|
|
Sends the tracee a
|
2007-06-21 05:38:48 +00:00
|
|
|
.B SIGKILL
|
|
|
|
to terminate it.
|
2006-03-25 21:28:28 +00:00
|
|
|
(\fIaddr\fP and \fIdata\fP are ignored.)
|
2011-09-24 06:29:34 +00:00
|
|
|
This operation is deprecated, use kill(SIGKILL) or tgkill(SIGKILL) instead.
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.B PTRACE_ATTACH
|
2004-11-03 13:51:07 +00:00
|
|
|
Attaches to the process specified in
|
|
|
|
.IR pid ,
|
2011-09-24 06:29:34 +00:00
|
|
|
making it a tracee of the calling process.
|
|
|
|
.\" Not true:
|
|
|
|
.\" ; the behavior of the tracee is as if it had done a
|
|
|
|
.\" .BR PTRACE_TRACEME .
|
|
|
|
.\" The calling process actually becomes the parent of the tracee
|
|
|
|
.\" process for most purposes (e.g., it will receive
|
|
|
|
.\" notification of tracee events and appears in
|
|
|
|
.\" .BR ps (1)
|
|
|
|
.\" output as the tracee's parent), but a
|
|
|
|
.\" .BR getppid (2)
|
|
|
|
.\" by the tracee will still return the PID of the original parent.
|
|
|
|
The tracee is sent a
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR SIGSTOP ,
|
|
|
|
but will not necessarily have stopped
|
2006-03-25 21:28:28 +00:00
|
|
|
by the completion of this call; use
|
2007-05-11 23:07:02 +00:00
|
|
|
.BR wait (2)
|
2011-09-24 06:29:34 +00:00
|
|
|
to wait for the tracee to stop. See "Attaching and detaching" subsection
|
|
|
|
for additional information.
|
2006-03-25 21:28:28 +00:00
|
|
|
(\fIaddr\fP and \fIdata\fP are ignored.)
|
2004-11-03 13:51:07 +00:00
|
|
|
.TP
|
2007-06-21 05:38:48 +00:00
|
|
|
.B PTRACE_DETACH
|
2011-09-24 06:29:34 +00:00
|
|
|
Restarts the stopped tracee as for
|
2007-06-21 05:38:48 +00:00
|
|
|
.BR PTRACE_CONT ,
|
2011-09-24 06:29:34 +00:00
|
|
|
but first detaches from it.
|
|
|
|
Under Linux a tracee can be
|
2006-03-25 21:28:28 +00:00
|
|
|
detached in this way regardless of which method was used to initiate
|
2007-04-12 22:42:49 +00:00
|
|
|
tracing.
|
2006-03-25 21:28:28 +00:00
|
|
|
(\fIaddr\fP is ignored.)
|
2011-09-24 06:29:34 +00:00
|
|
|
.\"
|
|
|
|
.\" In the text below, we decided to avoid prettifying the text with markup:
|
|
|
|
.\" it would make the source nearly impossible to edit, and we _do_ intend
|
|
|
|
.\" to edit it often, in order to keep it updated:
|
|
|
|
.\" ptrace API is full of quirks, no need to compound this situation by
|
|
|
|
.\" making it excruciatingly painful to document them!
|
|
|
|
.\"
|
|
|
|
.SS Death under ptrace
|
|
|
|
When a (possibly multi-threaded) process receives a killing signal (a
|
|
|
|
signal set to SIG_DFL and whose default action is to kill the process),
|
|
|
|
all threads exit. Tracees report their death to their tracer(s). The
|
|
|
|
notification about this event is delivered through waitpid API.
|
|
|
|
.LP
|
|
|
|
Note that killing signal will first cause signal-delivery-stop (on one
|
|
|
|
tracee only), and only after it is injected by tracer (or after it was
|
|
|
|
dispatched to a thread which isn't traced), death from signal will
|
|
|
|
happen on ALL tracees within multi-threaded process.
|
|
|
|
.LP
|
|
|
|
SIGKILL operates similarly, with exceptions. No signal-delivery-stop is
|
|
|
|
generated for SIGKILL and therefore tracer can't suppress it. SIGKILL
|
|
|
|
kills even within syscalls (syscall-exit-stop is not generated prior to
|
|
|
|
death by SIGKILL). The net effect is that SIGKILL always kills the
|
|
|
|
process (all its threads), even if some threads of the process are
|
|
|
|
ptraced.
|
|
|
|
.LP
|
|
|
|
Tracer can kill a tracee with ptrace(PTRACE_KILL, pid, 0, 0). This
|
|
|
|
operation is deprecated, use kill(SIGKILL) or tgkill(SIGKILL) instead.
|
|
|
|
The problem with this operation is that it requires tracee to be in
|
|
|
|
signal-delivery-stop, otherwise it may not work (may complete
|
|
|
|
successfully but won't kill the tracee), whereas tgkill(SIGKILL)
|
|
|
|
has no such limitation.
|
|
|
|
.LP
|
|
|
|
[Note: deprecation suggested by Oleg Nesterov. He prefers to deprecate
|
|
|
|
it instead of describing (and needing to support) PTRACE_KILL's quirks.]
|
|
|
|
.LP
|
|
|
|
When tracee executes exit syscall, it reports its death to its tracer.
|
|
|
|
Other threads are not affected.
|
|
|
|
.LP
|
|
|
|
When any thread executes exit_group syscall, every tracee in its thread
|
|
|
|
group reports its death to its tracer.
|
|
|
|
.LP
|
|
|
|
If PTRACE_O_TRACEEXIT option is on, PTRACE_EVENT_EXIT will happen
|
|
|
|
before actual death. This applies to exits on exit syscall, group_exit
|
|
|
|
syscall, signal deaths (except SIGKILL), and when threads are torn down
|
|
|
|
on execve in multi-threaded process.
|
|
|
|
.LP
|
|
|
|
Tracer cannot assume that ptrace-stopped tracee exists. There are many
|
|
|
|
scenarios when tracee may die while stopped (such as SIGKILL).
|
|
|
|
Therefore, tracer must always be prepared to handle ESRCH error on any
|
|
|
|
ptrace operation. Unfortunately, the same error is returned if tracee
|
|
|
|
exists but is not ptrace-stopped (for commands which require stopped
|
|
|
|
tracee), or if it is not traced by process which issued ptrace call.
|
|
|
|
Tracer needs to keep track of stopped/running state, and interpret
|
|
|
|
ESRCH as "tracee died unexpectedly" only if it knows that tracee has
|
|
|
|
been observed to enter ptrace-stop. Note that there is no guarantee
|
|
|
|
that waitpid(WNOHANG) will reliably report tracee's death status if
|
|
|
|
ptrace operation returned ESRCH. waitpid(WNOHANG) may return 0 instead.
|
|
|
|
IOW: tracee may be "not yet fully dead" but already refusing ptrace ops.
|
|
|
|
.LP
|
|
|
|
Tracer can not assume that tracee ALWAYS ends its life by reporting
|
|
|
|
WIFEXITED(status) or WIFSIGNALED(status).
|
|
|
|
.LP
|
|
|
|
.\" or can it? Do we include such a promise into ptrace API?
|
|
|
|
.SS Stopped states
|
|
|
|
A tracee can be in two states: running or stopped.
|
|
|
|
.LP
|
|
|
|
There are many kinds of states when tracee is stopped, and in ptrace
|
|
|
|
discussions they are often conflated. Therefore, it is important to use
|
|
|
|
precise terms.
|
|
|
|
.LP
|
|
|
|
In this document, any stopped state in which tracee is ready to accept
|
|
|
|
ptrace commands from the tracer is called ptrace-stop. Ptrace-stops can
|
|
|
|
be further subdivided into signal-delivery-stop, group-stop,
|
|
|
|
syscall-stop and so on. They are described in detail later.
|
|
|
|
.LP
|
|
|
|
When running tracee enters ptrace-stop, it notifies its tracer using
|
|
|
|
waitpid API. Tracer should use waitpid family of syscalls to wait for
|
|
|
|
tracee to stop. Most of this document assumes that tracer waits with:
|
|
|
|
.LP
|
|
|
|
pid = waitpid(pid_or_minus_1, &status, __WALL);
|
|
|
|
.LP
|
|
|
|
Ptrace-stopped tracees are reported as returns with pid > 0 and
|
|
|
|
WIFSTOPPED(status) == true.
|
|
|
|
.LP
|
|
|
|
.\" Do we require __WALL usage, or will just using 0 be ok? Are the
|
|
|
|
.\" rules different if user wants to use waitid? Will waitid require
|
|
|
|
.\" WEXITED?
|
|
|
|
.LP
|
|
|
|
__WALL value does not include WSTOPPED and WEXITED bits, but implies
|
|
|
|
their functionality.
|
|
|
|
.LP
|
|
|
|
Setting of WCONTINUED bit in waitpid flags is not recommended: the
|
|
|
|
continued state is per-process and consuming it can confuse real parent
|
|
|
|
of the tracee.
|
|
|
|
.LP
|
|
|
|
Use of WNOHANG bit in waitpid flags may cause waitpid return 0 ("no
|
|
|
|
wait results available yet") even if tracer knows there should be a
|
|
|
|
notification. Example: kill(tracee, SIGKILL); waitpid(tracee, &status,
|
|
|
|
__WALL | WNOHANG);
|
|
|
|
.\" waitid usage? WNOWAIT?
|
|
|
|
.\" describe how wait notifications queue (or not queue)
|
|
|
|
.LP
|
|
|
|
The following kinds of ptrace-stops exist: signal-delivery-stops,
|
|
|
|
group-stop, PTRACE_EVENT stops, syscall-stops [, SINGLESTEP, SYSEMU,
|
|
|
|
SYSEMU_SINGLESTEP]. They all are reported as waitpid result with
|
|
|
|
WIFSTOPPED(status) == true. They may be differentiated by checking
|
|
|
|
(status >> 8) value, and if looking at (status >> 8) value doesn't
|
|
|
|
resolve ambiguity, by querying PTRACE_GETSIGINFO. (Note:
|
|
|
|
WSTOPSIG(status) macro returns ((status >> 8) & 0xff) value).
|
|
|
|
.SS Signal-delivery-stop
|
|
|
|
When (possibly multi-threaded) process receives any signal except
|
|
|
|
SIGKILL, kernel selects a thread which handles the signal (if signal is
|
|
|
|
generated with t[g]kill, thread selection is done by user). If selected
|
|
|
|
thread is traced, it enters signal-delivery-stop. By this point, signal
|
|
|
|
is not yet delivered to the process, and can be suppressed by tracer.
|
|
|
|
If tracer doesn't suppress the signal, it passes signal to tracee in
|
|
|
|
the next ptrace request. This second step of signal delivery is called
|
|
|
|
"signal injection" in this document. Note that if signal is blocked,
|
|
|
|
signal-delivery-stop doesn't happen until signal is unblocked, with the
|
|
|
|
usual exception that SIGSTOP can't be blocked.
|
|
|
|
.LP
|
|
|
|
Signal-delivery-stop is observed by tracer as waitpid returning with
|
|
|
|
WIFSTOPPED(status) == true, WSTOPSIG(status) == signal. If
|
|
|
|
WSTOPSIG(status) == SIGTRAP, this may be a different kind of
|
|
|
|
ptrace-stop - see "Syscall-stops" and "execve" sections below for
|
|
|
|
details. If WSTOPSIG(status) == stopping signal, this may be a
|
|
|
|
group-stop - see below.
|
|
|
|
.SS Signal injection and suppression
|
|
|
|
After signal-delivery-stop is observed by tracer, tracer should restart
|
|
|
|
tracee with
|
|
|
|
.LP
|
|
|
|
ptrace(PTRACE_rest, pid, 0, sig)
|
|
|
|
.LP
|
|
|
|
call, where PTRACE_rest is one of the restarting ptrace ops. If sig is
|
|
|
|
0, then signal is not delivered. Otherwise, signal sig is delivered.
|
|
|
|
This operation is called "signal injection" in this document, to
|
|
|
|
distinguish it from signal-delivery-stop.
|
|
|
|
.LP
|
|
|
|
Note that sig value may be different from WSTOPSIG(status) value -
|
|
|
|
tracer can cause a different signal to be injected.
|
|
|
|
.LP
|
|
|
|
Note that suppressed signal still causes syscalls to return
|
|
|
|
prematurely. Restartable syscalls will be restarted (tracer will
|
|
|
|
observe tracee to execute restart_syscall(2) syscall if tracer uses
|
|
|
|
PTRACE_SYSCALL), non-restartable syscalls (for example, nanosleep) may
|
|
|
|
return with -EINTR even though no observable signal is injected to the
|
|
|
|
tracee.
|
|
|
|
.LP
|
|
|
|
Note that restarting ptrace commands issued in ptrace-stops other than
|
|
|
|
signal-delivery-stop are not guaranteed to inject a signal, even if sig
|
|
|
|
is nonzero. No error is reported, nonzero sig may simply be ignored.
|
|
|
|
Ptrace users should not try to "create new signal" this way: use
|
|
|
|
tgkill(2) instead.
|
|
|
|
.LP
|
|
|
|
This is a cause of confusion among ptrace users. One typical scenario
|
|
|
|
is that tracer observes group-stop, mistakes it for
|
|
|
|
signal-delivery-stop, restarts tracee with ptrace(PTRACE_rest, pid, 0,
|
|
|
|
stopsig) with the intention of injecting stopsig, but stopsig gets
|
|
|
|
ignored and tracee continues to run.
|
|
|
|
.LP
|
|
|
|
SIGCONT signal has a side effect of waking up (all threads of)
|
|
|
|
group-stopped process. This side effect happens before
|
|
|
|
signal-delivery-stop. Tracer can't suppress this side-effect (it can
|
|
|
|
only suppress signal injection, which only causes SIGCONT handler to
|
|
|
|
not be executed in the tracee, if such handler is installed). In fact,
|
|
|
|
waking up from group-stop may be followed by signal-delivery-stop for
|
|
|
|
signal(s) *other than* SIGCONT, if they were pending when SIGCONT was
|
|
|
|
delivered. IOW: SIGCONT may be not the first signal observed by the
|
|
|
|
tracee after it was sent.
|
|
|
|
.LP
|
|
|
|
Stopping signals cause (all threads of) process to enter group-stop.
|
|
|
|
This side effect happens after signal injection, and therefore can be
|
|
|
|
suppressed by tracer.
|
|
|
|
.LP
|
|
|
|
PTRACE_GETSIGINFO can be used to retrieve siginfo_t structure which
|
|
|
|
corresponds to delivered signal. PTRACE_SETSIGINFO may be used to
|
|
|
|
modify it. If PTRACE_SETSIGINFO has been used to alter siginfo_t,
|
|
|
|
si_signo field and sig parameter in restarting command must match,
|
|
|
|
otherwise the result is undefined.
|
|
|
|
.SS Group-stop
|
|
|
|
When a (possibly multi-threaded) process receives a stopping signal,
|
|
|
|
all threads stop. If some threads are traced, they enter a group-stop.
|
|
|
|
Note that stopping signal will first cause signal-delivery-stop (on one
|
|
|
|
tracee only), and only after it is injected by tracer (or after it was
|
|
|
|
dispatched to a thread which isn't traced), group-stop will be
|
|
|
|
initiated on ALL tracees within multi-threaded process. As usual, every
|
|
|
|
tracee reports its group-stop separately to corresponding tracer.
|
|
|
|
.LP
|
|
|
|
Group-stop is observed by tracer as waitpid returning with
|
|
|
|
WIFSTOPPED(status) == true, WSTOPSIG(status) == signal. The same result
|
|
|
|
is returned by some other classes of ptrace-stops, therefore the
|
|
|
|
recommended practice is to perform
|
|
|
|
.LP
|
|
|
|
ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo)
|
|
|
|
.LP
|
|
|
|
call. The call can be avoided if signal number is not SIGSTOP, SIGTSTP,
|
|
|
|
SIGTTIN or SIGTTOU - only these four signals are stopping signals. If
|
|
|
|
tracer sees something else, it can't be group-stop. Otherwise, tracer
|
|
|
|
needs to call PTRACE_GETSIGINFO. If PTRACE_GETSIGINFO fails with
|
|
|
|
EINVAL, then it is definitely a group-stop. (Other failure codes are
|
|
|
|
possible, such as ESRCH "no such process" if SIGKILL killed the tracee).
|
|
|
|
.LP
|
|
|
|
As of kernel 2.6.38, after tracer sees tracee ptrace-stop and until it
|
|
|
|
restarts or kills it, tracee will not run, and will not send
|
|
|
|
notifications (except SIGKILL death) to tracer, even if tracer enters
|
|
|
|
into another waitpid call.
|
|
|
|
.LP
|
|
|
|
Currently, it causes a problem with transparent handling of stopping
|
|
|
|
signals: if tracer restarts tracee after group-stop, SIGSTOP is
|
|
|
|
effectively ignored: tracee doesn't remain stopped, it runs. If tracer
|
|
|
|
doesn't restart tracee before entering into next waitpid, future
|
|
|
|
SIGCONT will not be reported to the tracer. Which would make SIGCONT to
|
|
|
|
have no effect.
|
|
|
|
.SS PTRACE_EVENT stops
|
|
|
|
If tracer sets TRACE_O_TRACEfoo options, tracee will enter ptrace-stops
|
|
|
|
called PTRACE_EVENT stops.
|
|
|
|
.LP
|
|
|
|
PTRACE_EVENT stops are observed by tracer as waitpid returning with
|
|
|
|
WIFSTOPPED(status) == true, WSTOPSIG(status) == SIGTRAP. Additional bit
|
|
|
|
is set in a higher byte of status word: value (status >> 8)
|
|
|
|
will be (SIGTRAP | PTRACE_EVENT_foo << 8). The following events exist:
|
|
|
|
.LP
|
|
|
|
PTRACE_EVENT_VFORK - stop before return from vfork or clone+CLONE_VFORK.
|
|
|
|
When tracee is continued after this stop, it will wait for child to
|
|
|
|
exit/exec before continuing its execution (IOW: usual behavior on
|
|
|
|
vfork).
|
|
|
|
.LP
|
|
|
|
PTRACE_EVENT_FORK - stop before return from fork or clone+SIGCHLD
|
|
|
|
.LP
|
|
|
|
PTRACE_EVENT_CLONE - stop before return from clone
|
|
|
|
.LP
|
|
|
|
PTRACE_EVENT_VFORK_DONE - stop before return from
|
|
|
|
vfork or clone+CLONE_VFORK, but after vforked child unblocked this
|
|
|
|
tracee by exiting or exec'ing.
|
|
|
|
.LP
|
|
|
|
For all four stops described above: stop occurs in parent, not in newly
|
|
|
|
created thread. PTRACE_GETEVENTMSG can be used to retrieve new thread's
|
|
|
|
tid.
|
|
|
|
.LP
|
|
|
|
PTRACE_EVENT_EXEC - stop before return from execve.
|
|
|
|
.LP
|
|
|
|
PTRACE_EVENT_EXIT - stop before exit (including death from exit_group),
|
|
|
|
signal death, or exit caused by execve in multi-threaded process.
|
|
|
|
PTRACE_GETEVENTMSG returns exit status. Registers can be examined
|
|
|
|
(unlike when "real" exit happens). The tracee is still alive, it needs
|
|
|
|
to be PTRACE_CONTed or PTRACE_DETACHed to finish exit.
|
|
|
|
.LP
|
|
|
|
PTRACE_GETSIGINFO on PTRACE_EVENT stops returns si_signo = SIGTRAP,
|
|
|
|
si_code = (event << 8) | SIGTRAP.
|
|
|
|
.SS Syscall-stops
|
|
|
|
If tracee was restarted by PTRACE_SYSCALL, tracee enters
|
|
|
|
syscall-enter-stop just prior to entering any syscall. If tracer
|
|
|
|
restarts it with PTRACE_SYSCALL, tracee enters syscall-exit-stop when
|
|
|
|
syscall is finished, or if it is interrupted by a signal. (That is,
|
|
|
|
signal-delivery-stop never happens between syscall-enter-stop and
|
|
|
|
syscall-exit-stop, it happens *after* syscall-exit-stop).
|
|
|
|
.LP
|
|
|
|
Other possibilities are that tracee may stop in a PTRACE_EVENT stop,
|
|
|
|
exit (if it entered exit or exit_group syscall), be killed by SIGKILL,
|
|
|
|
or die silently (if it is a thread group leader, execve syscall happened
|
|
|
|
in another thread, and that thread is not traced by the same tracer -
|
|
|
|
this sutuation is discussed later).
|
|
|
|
.LP
|
|
|
|
Syscall-enter-stop and syscall-exit-stop are observed by tracer as
|
|
|
|
waitpid returning with WIFSTOPPED(status) == true, WSTOPSIG(status) ==
|
|
|
|
SIGTRAP. If PTRACE_O_TRACESYSGOOD option was set by tracer, then
|
|
|
|
WSTOPSIG(status) == (SIGTRAP | 0x80).
|
|
|
|
.LP
|
|
|
|
Syscall-stops can be distinguished from signal-delivery-stop with
|
|
|
|
SIGTRAP by querying PTRACE_GETSIGINFO: si_code <= 0 if SIGTRAP was sent by usual
|
|
|
|
suspects like [tg]kill/sigqueue/etc; or = SI_KERNEL (0x80) if sent by
|
|
|
|
kernel, whereas syscall-stops have si_code = SIGTRAP or (SIGTRAP |
|
|
|
|
0x80). However, syscall-stops happen very often (twice per syscall),
|
|
|
|
and performing PTRACE_GETSIGINFO for every syscall-stop may be somewhat
|
|
|
|
expensive.
|
|
|
|
.LP
|
|
|
|
Some architectures allow to distinguish them by examining registers.
|
|
|
|
For example, on x86 rax = -ENOSYS in syscall-enter-stop. Since SIGTRAP
|
|
|
|
(like any other signal) always happens *after* syscall-exit-stop, and
|
|
|
|
at this point rax almost never contains -ENOSYS, SIGTRAP looks like
|
|
|
|
"syscall-stop which is not syscall-enter-stop", IOW: it looks like a
|
|
|
|
"stray syscall-exit-stop" and can be detected this way. But such
|
|
|
|
detection is fragile and is best avoided.
|
|
|
|
.LP
|
|
|
|
Using PTRACE_O_TRACESYSGOOD option is a recommended method, since it is
|
|
|
|
reliable and does not incur performance penalty.
|
|
|
|
.LP
|
|
|
|
Syscall-enter-stop and syscall-exit-stop are indistinguishable from
|
|
|
|
each other by tracer. Tracer needs to keep track of the sequence of
|
|
|
|
ptrace-stops in order to not misinterpret syscall-enter-stop as
|
|
|
|
syscall-exit-stop or vice versa. The rule is that syscall-enter-stop is
|
|
|
|
always followed by syscall-exit-stop, PTRACE_EVENT stop or tracee's
|
|
|
|
death - no other kinds of ptrace-stop can occur in between.
|
|
|
|
.LP
|
|
|
|
If after syscall-enter-stop tracer uses restarting command other than
|
|
|
|
PTRACE_SYSCALL, syscall-exit-stop is not generated.
|
|
|
|
.LP
|
|
|
|
PTRACE_GETSIGINFO on syscall-stops returns si_signo = SIGTRAP, si_code
|
|
|
|
= SIGTRAP or (SIGTRAP | 0x80).
|
|
|
|
.SS SINGLESTEP, SYSEMU, SYSEMU_SINGLESTEP stops
|
|
|
|
(TODO: document stops occurring with PTRACE_SINGLESTEP, PTRACE_SYSEMU,
|
|
|
|
PTRACE_SYSEMU_SINGLESTEP)
|
|
|
|
.SS Informational and restarting ptrace commands
|
|
|
|
Most ptrace commands (all except ATTACH, TRACEME, KILL) require tracee
|
|
|
|
to be in a ptrace-stop, otherwise they fail with ESRCH.
|
|
|
|
.LP
|
|
|
|
When tracee is in ptrace-stop, tracer can read and write data to tracee
|
|
|
|
using informational commands. They leave tracee in ptrace-stopped state:
|
|
|
|
.LP
|
|
|
|
.nf
|
|
|
|
longv = ptrace(PTRACE_PEEKTEXT/PEEKDATA/PEEKUSER, pid, addr, 0);
|
|
|
|
ptrace(PTRACE_POKETEXT/POKEDATA/POKEUSER, pid, addr, long_val);
|
|
|
|
ptrace(PTRACE_GETREGS/GETFPREGS, pid, 0, &struct);
|
|
|
|
ptrace(PTRACE_SETREGS/SETFPREGS, pid, 0, &struct);
|
|
|
|
ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo);
|
|
|
|
ptrace(PTRACE_SETSIGINFO, pid, 0, &siginfo);
|
|
|
|
ptrace(PTRACE_GETEVENTMSG, pid, 0, &long_var);
|
|
|
|
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags);
|
|
|
|
.fi
|
|
|
|
.LP
|
|
|
|
Note that some errors are not reported. For example, setting siginfo
|
|
|
|
may have no effect in some ptrace-stops, yet the call may succeed
|
|
|
|
(return 0 and don't set errno); querying GETEVENTMSG may succeed
|
|
|
|
and return some random value if current ptrace-stop is not documented
|
|
|
|
as returning meaningful event message.
|
|
|
|
.LP
|
|
|
|
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags) affects one tracee.
|
|
|
|
Current flags are replaced. Flags are inherited by new tracees created
|
|
|
|
and "auto-attached" via active PTRACE_O_TRACE[V]FORK or
|
|
|
|
PTRACE_O_TRACECLONE options.
|
|
|
|
.LP
|
|
|
|
Another group of commands makes ptrace-stopped tracee run. They have
|
|
|
|
the form:
|
|
|
|
.LP
|
|
|
|
ptrace(PTRACE_cmd, pid, 0, sig);
|
|
|
|
.LP
|
|
|
|
where cmd is CONT, DETACH, SYSCALL, SINGLESTEP, SYSEMU, or
|
|
|
|
SYSEMU_SINGLESTEP. If tracee is in signal-delivery-stop, sig is the
|
|
|
|
signal to be injected. Otherwise, sig may be ignored (recommended
|
|
|
|
practice is to always pass 0 in these cases).
|
|
|
|
.SS Attaching and detaching
|
|
|
|
A thread can be attached to tracer using ptrace(PTRACE_ATTACH, pid, 0,
|
|
|
|
0) call. This also sends SIGSTOP to this thread. If tracer wants this
|
|
|
|
SIGSTOP to have no effect, it needs to suppress it. Note that if other
|
|
|
|
signals are concurrently sent to this thread during attach, tracer may
|
|
|
|
see tracee enter signal-delivery-stop with other signal(s) first! The
|
|
|
|
usual practice is to reinject these signals until SIGSTOP is seen, then
|
|
|
|
suppress SIGSTOP injection. The design bug here is that attach and
|
|
|
|
concurrent SIGSTOP are racing and concurrent SIGSTOP may be lost.
|
|
|
|
.\" Describe how to attach to a thread which is already group-stopped.
|
|
|
|
.LP
|
|
|
|
Since attaching sends SIGSTOP and tracer usually suppresses it, this
|
|
|
|
may cause stray EINTR return from the currently executing syscall in
|
|
|
|
the tracee, as described in "signal injection and suppression" section.
|
|
|
|
.LP
|
|
|
|
ptrace(PTRACE_TRACEME, 0, 0, 0) request turns current thread into a
|
|
|
|
tracee. It continues to run (doesn't enter ptrace-stop). A common
|
|
|
|
practice is to follow ptrace(PTRACE_TRACEME) with raise(SIGSTOP) and
|
|
|
|
allow parent (which is our tracer now) to observe our
|
|
|
|
signal-delivery-stop.
|
|
|
|
.LP
|
|
|
|
If PTRACE_O_TRACE[V]FORK or PTRACE_O_TRACECLONE options are in effect,
|
|
|
|
then children created by (vfork or clone(CLONE_VFORK)), (fork or
|
|
|
|
clone(SIGCHLD)) and (other kinds of clone) respectively are
|
|
|
|
automatically attached to the same tracer which traced their parent.
|
|
|
|
SIGSTOP is delivered to them, causing them to enter
|
|
|
|
signal-delivery-stop after they exit syscall which created them.
|
|
|
|
.LP
|
|
|
|
Detaching of tracee is performed by ptrace(PTRACE_DETACH, pid, 0, sig).
|
|
|
|
PTRACE_DETACH is a restarting operation, therefore it requires tracee
|
|
|
|
to be in ptrace-stop. If tracee is in signal-delivery-stop, signal can
|
|
|
|
be injected. Otherwise, sig parameter may be silently ignored.
|
|
|
|
.LP
|
|
|
|
If tracee is running when tracer wants to detach it, the usual solution
|
|
|
|
is to send SIGSTOP (using tgkill, to make sure it goes to the correct
|
|
|
|
thread), wait for tracee to stop in signal-delivery-stop for SIGSTOP
|
|
|
|
and then detach it (suppressing SIGSTOP injection). Design bug is that
|
|
|
|
this can race with concurrent SIGSTOPs. Another complication is that
|
|
|
|
tracee may enter other ptrace-stops and needs to be restarted and
|
|
|
|
waited for again, until SIGSTOP is seen. Yet another complication is to
|
|
|
|
be sure that tracee is not already ptrace-stopped, because no signal
|
|
|
|
delivery happens while it is - not even SIGSTOP.
|
|
|
|
.\" Describe how to detach from a group-stopped tracee so that it
|
|
|
|
.\" doesn't run, but continues to wait for SIGCONT.
|
|
|
|
.LP
|
|
|
|
If tracer dies, all tracees are automatically detached and restarted,
|
|
|
|
unless they were in group-stop. Handling of restart from group-stop is
|
|
|
|
currently buggy, but "as planned" behavior is to leave tracee stopped
|
|
|
|
and waiting for SIGCONT. If tracee is restarted from
|
|
|
|
signal-delivery-stop, pending signal is injected.
|
|
|
|
.SS execve under ptrace
|
|
|
|
During execve, kernel destroys all other threads in the process, and
|
|
|
|
resets execve'ing thread tid to tgid (process id). This looks very
|
|
|
|
confusing to tracers:
|
|
|
|
.LP
|
|
|
|
All other threads stop in PTRACE_EXIT stop, if requested by active
|
|
|
|
ptrace option. Then all other threads except thread group leader report
|
|
|
|
death as if they exited via exit syscall with exit code 0. Then
|
|
|
|
PTRACE_EVENT_EXEC stop happens, if requested by active ptrace option.
|
|
|
|
.\" (on which tracee - leader? execve-ing one?)
|
|
|
|
.LP
|
|
|
|
The execve-ing tracee changes its pid while it is in execve syscall.
|
|
|
|
(Remember, under ptrace 'pid' returned from waitpid, or fed into ptrace
|
|
|
|
calls, is tracee's tid). That is, pid is reset to process id, which
|
|
|
|
coincides with thread group leader tid.
|
|
|
|
.LP
|
|
|
|
If thread group leader has reported its death by this time, for tracer
|
|
|
|
this looks like dead thread leader "reappears from nowhere". If thread
|
|
|
|
group leader was still alive, for tracer this may look as if thread
|
|
|
|
group leader returns from a different syscall than it entered, or even
|
|
|
|
"returned from syscall even though it was not in any syscall". If
|
|
|
|
thread group leader was not traced (or was traced by a different
|
|
|
|
tracer), during execve it will appear as if it has become a tracee of
|
|
|
|
the tracer of execve-ing tracee. All these effects are the artifacts of
|
|
|
|
pid change.
|
|
|
|
.LP
|
|
|
|
PTRACE_O_TRACEEXEC option is the recommended tool for dealing with this
|
|
|
|
case. It enables PTRACE_EVENT_EXEC stop which occurs before execve
|
|
|
|
syscall returns.
|
|
|
|
.LP
|
|
|
|
Pid change happens before PTRACE_EVENT_EXEC stop, not after.
|
|
|
|
.LP
|
|
|
|
When tracer receives PTRACE_EVENT_EXEC stop notification, it is
|
|
|
|
guaranteed that except this tracee and thread group leader, no other
|
|
|
|
threads from the process are alive.
|
|
|
|
.LP
|
|
|
|
On receiving this notification, tracer should clean up all its internal
|
|
|
|
data structures about all threads of this process, and retain only one
|
|
|
|
data structure, one which describes single still running tracee, with
|
|
|
|
pid = tgid = process id.
|
|
|
|
.LP
|
|
|
|
Currently, there is no way to retrieve former pid of execve-ing tracee.
|
|
|
|
If tracer doesn't keep track of its tracees' thread group relations, it
|
|
|
|
may be unable to know which tracee execve-ed and therefore no longer
|
|
|
|
exists under old pid due to pid change.
|
|
|
|
.LP
|
|
|
|
Example: two threads execve at the same time:
|
|
|
|
.LP
|
|
|
|
.nf
|
|
|
|
*** we get syscall-entry-stop in thread 1: **
|
|
|
|
PID1 execve("/bin/foo", "foo" <unfinished ...>
|
|
|
|
*** we issue PTRACE_SYSCALL for thread 1 **
|
|
|
|
*** we get syscall-entry-stop in thread 2: **
|
|
|
|
PID2 execve("/bin/bar", "bar" <unfinished ...>
|
|
|
|
*** we issue PTRACE_SYSCALL for thread 2 **
|
|
|
|
*** we get PTRACE_EVENT_EXEC for PID0, we issue PTRACE_SYSCALL **
|
|
|
|
*** we get syscall-exit-stop for PID0: **
|
|
|
|
PID0 <... execve resumed> ) = 0
|
|
|
|
.fi
|
|
|
|
.LP
|
|
|
|
In this situation there is no way to know which execve succeeded.
|
|
|
|
.LP
|
|
|
|
If PTRACE_O_TRACEEXEC option is NOT in effect for the execve-ing
|
|
|
|
tracee, kernel delivers an extra SIGTRAP to tracee after execve syscall
|
|
|
|
returns. This is an ordinary signal (similar to one which can be
|
|
|
|
generated by "kill -TRAP"), not a special kind of ptrace-stop.
|
|
|
|
GETSIGINFO on it has si_code = 0 (SI_USER). It can be blocked by signal
|
|
|
|
mask, and thus can happen (much) later.
|
|
|
|
.LP
|
|
|
|
Usually, tracer (for example, strace) would not want to show this extra
|
|
|
|
post-execve SIGTRAP signal to the user, and would suppress its delivery
|
|
|
|
to the tracee (if SIGTRAP is set to SIG_DFL, it is a killing signal).
|
|
|
|
However, determining *which* SIGTRAP to suppress is not easy. Setting
|
|
|
|
PTRACE_O_TRACEEXEC option and thus suppressing this extra SIGTRAP is
|
|
|
|
the recommended approach.
|
|
|
|
.SS Real parent
|
|
|
|
Ptrace API (ab)uses standard Unix parent/child signaling over waitpid.
|
|
|
|
This used to cause real parent of the process to stop receiving several
|
|
|
|
kinds of waitpid notifications when child process is traced by some
|
|
|
|
other process.
|
|
|
|
.LP
|
|
|
|
Many of these bugs have been fixed, but as of 2.6.38 several still
|
|
|
|
exist - see BUGS section below.
|
|
|
|
.LP
|
|
|
|
As of 2.6.38, the following is believed to work correctly:
|
|
|
|
.LP
|
|
|
|
* exit/death by signal is reported first to tracer, then, when tracer
|
|
|
|
consumes waitpid result, to real parent (to real parent only when the
|
|
|
|
whole multi-threaded process exits). If they are the same process, the
|
|
|
|
report is sent only once.
|
2007-05-19 04:30:20 +00:00
|
|
|
.SH "RETURN VALUE"
|
2007-06-21 22:55:04 +00:00
|
|
|
On success,
|
2007-09-20 16:26:31 +00:00
|
|
|
.B PTRACE_PEEK*
|
2007-06-21 05:38:48 +00:00
|
|
|
requests return the requested data,
|
2007-05-19 04:30:20 +00:00
|
|
|
while other requests return zero.
|
|
|
|
On error, all requests return \-1, and
|
|
|
|
.I errno
|
|
|
|
is set appropriately.
|
2007-06-21 05:38:48 +00:00
|
|
|
Since the value returned by a successful
|
2007-09-20 16:26:31 +00:00
|
|
|
.B PTRACE_PEEK*
|
2007-05-19 04:30:20 +00:00
|
|
|
request may be \-1, the caller must check
|
|
|
|
.I errno
|
|
|
|
after such requests to determine whether or not an error occurred.
|
|
|
|
.SH ERRORS
|
|
|
|
.TP
|
|
|
|
.B EBUSY
|
|
|
|
(i386 only) There was an error with allocating or freeing a debug
|
|
|
|
register.
|
|
|
|
.TP
|
|
|
|
.B EFAULT
|
|
|
|
There was an attempt to read from or write to an invalid area in
|
2011-09-24 06:29:34 +00:00
|
|
|
the tracer's or tracee's memory,
|
2007-05-19 04:30:20 +00:00
|
|
|
probably because the area wasn't mapped or accessible.
|
|
|
|
Unfortunately, under Linux, different variations of this fault
|
2007-06-22 19:42:52 +00:00
|
|
|
will return
|
|
|
|
.B EIO
|
|
|
|
or
|
|
|
|
.B EFAULT
|
|
|
|
more or less arbitrarily.
|
2007-05-19 04:30:20 +00:00
|
|
|
.TP
|
|
|
|
.B EINVAL
|
|
|
|
An attempt was made to set an invalid option.
|
|
|
|
.TP
|
|
|
|
.B EIO
|
|
|
|
\fIrequest\fP is invalid, or an attempt was made to read from or
|
2011-09-24 06:29:34 +00:00
|
|
|
write to an invalid area in the tracer's or tracee's memory,
|
2007-05-19 04:30:20 +00:00
|
|
|
or there was a word-alignment violation,
|
|
|
|
or an invalid signal was specified during a restart request.
|
|
|
|
.TP
|
|
|
|
.B EPERM
|
|
|
|
The specified process cannot be traced.
|
|
|
|
This could be because the
|
2011-09-24 06:29:34 +00:00
|
|
|
tracer has insufficient privileges (the required capability is
|
2007-05-19 04:30:20 +00:00
|
|
|
.BR CAP_SYS_PTRACE );
|
2010-01-16 17:24:09 +00:00
|
|
|
unprivileged processes cannot trace processes that they
|
2007-05-19 04:30:20 +00:00
|
|
|
cannot send signals to or those running
|
|
|
|
set-user-ID/set-group-ID programs, for obvious reasons.
|
|
|
|
Alternatively, the process may already be being traced, or be
|
2007-06-23 07:19:07 +00:00
|
|
|
.BR init (8)
|
2007-05-19 04:30:20 +00:00
|
|
|
(PID 1).
|
|
|
|
.TP
|
|
|
|
.B ESRCH
|
|
|
|
The specified process does not exist, or is not currently being traced
|
|
|
|
by the caller, or is not stopped (for requests that require that).
|
|
|
|
.SH "CONFORMING TO"
|
2008-07-15 13:39:17 +00:00
|
|
|
SVr4, 4.3BSD.
|
2004-11-03 13:51:07 +00:00
|
|
|
.SH NOTES
|
|
|
|
Although arguments to
|
2005-10-19 06:54:38 +00:00
|
|
|
.BR ptrace ()
|
2007-04-12 22:42:49 +00:00
|
|
|
are interpreted according to the prototype given,
|
2007-07-09 22:01:31 +00:00
|
|
|
glibc currently declares
|
2005-10-19 06:54:38 +00:00
|
|
|
.BR ptrace ()
|
2007-04-12 22:42:49 +00:00
|
|
|
as a variadic function with only the \fIrequest\fP argument fixed.
|
|
|
|
This means that unneeded trailing arguments may be omitted,
|
2006-03-25 21:28:28 +00:00
|
|
|
though doing so makes use of undocumented
|
2005-11-02 10:53:26 +00:00
|
|
|
.BR gcc (1)
|
2004-11-03 13:51:07 +00:00
|
|
|
behavior.
|
2011-09-24 06:29:34 +00:00
|
|
|
.\" Not true anymore:
|
|
|
|
.\" .LP
|
|
|
|
.\" .BR init (8),
|
|
|
|
.\" the process with PID 1, may not be traced.
|
|
|
|
.\" .LP
|
2004-11-03 13:51:07 +00:00
|
|
|
The layout of the contents of memory and the USER area are quite OS- and
|
|
|
|
architecture-specific.
|
2008-05-21 20:23:25 +00:00
|
|
|
The offset supplied, and the data returned,
|
|
|
|
might not entirely match with the definition of
|
|
|
|
.IR "struct user" .
|
|
|
|
.\" See http://lkml.org/lkml/2008/5/8/375
|
2004-11-03 13:51:07 +00:00
|
|
|
.LP
|
2007-04-12 22:42:49 +00:00
|
|
|
The size of a "word" is determined by the OS variant
|
2007-06-02 05:45:14 +00:00
|
|
|
(e.g., for 32-bit Linux it is 32 bits, etc.).
|
2011-09-24 06:29:34 +00:00
|
|
|
.\" Covered in more details above:
|
|
|
|
.\" .LP
|
|
|
|
.\" Tracing causes a few subtle differences in the semantics of
|
|
|
|
.\" traced processes.
|
|
|
|
.\" For example, if a process is attached to with
|
|
|
|
.\" .BR PTRACE_ATTACH ,
|
|
|
|
.\" its original parent can no longer receive notification via
|
|
|
|
.\" .BR wait (2)
|
|
|
|
.\" when it stops, and there is no way for the new parent to
|
|
|
|
.\" effectively simulate this notification.
|
|
|
|
.\" .LP
|
|
|
|
.\" When the parent receives an event with
|
|
|
|
.\" .B PTRACE_EVENT_*
|
|
|
|
.\" set,
|
|
|
|
.\" the tracee is not in the normal signal delivery path.
|
|
|
|
.\" This means the parent cannot do
|
|
|
|
.\" .BR ptrace (PTRACE_CONT)
|
|
|
|
.\" with a signal or
|
|
|
|
.\" .BR ptrace (PTRACE_KILL).
|
|
|
|
.\" .BR kill (2)
|
|
|
|
.\" with a
|
|
|
|
.\" .B SIGKILL
|
|
|
|
.\" signal can be used instead to kill the tracee
|
|
|
|
.\" after receiving one of these messages.
|
|
|
|
.\" .LP
|
2004-11-03 13:51:07 +00:00
|
|
|
This page documents the way the
|
2005-10-19 06:54:38 +00:00
|
|
|
.BR ptrace ()
|
2007-04-12 22:42:49 +00:00
|
|
|
call works currently in Linux.
|
intro.1, time.1, accept.2, bind.2, connect.2, execve.2, flock.2, getdents.2, getpriority.2, getuid.2, intro.2, ioctl.2, mincore.2, mknod.2, personality.2, ptrace.2, read.2, recv.2, select_tut.2, send.2, sendfile.2, shmctl.2, sigaction.2, signal.2, stat.2, times.2, truncate.2, umask.2, wait.2, MB_CUR_MAX.3, MB_LEN_MAX.3, argz_add.3, btowc.3, clearenv.3, clock.3, cmsg.3, end.3, endian.3, errno.3, exit.3, fgetwc.3, fgetws.3, fopen.3, fputwc.3, fputws.3, fseek.3, fwide.3, getfsent.3, getgrnam.3, gethostid.3, getipnodebyname.3, getmntent.3, getpwnam.3, getwchar.3, grantpt.3, iconv.3, iconv_close.3, iconv_open.3, insque.3, intro.3, iswalnum.3, iswalpha.3, iswblank.3, iswcntrl.3, iswctype.3, iswdigit.3, iswgraph.3, iswlower.3, iswprint.3, iswpunct.3, iswspace.3, iswupper.3, iswxdigit.3, malloc.3, mblen.3, mbrlen.3, mbrtowc.3, mbsinit.3, mbsnrtowcs.3, mbsrtowcs.3, mbstowcs.3, mbtowc.3, mkstemp.3, mktemp.3, nl_langinfo.3, openpty.3, posix_openpt.3, printf.3, ptsname.3, putwchar.3, qecvt.3, rcmd.3, readdir.3, rexec.3, rpc.3, setnetgrent.3, shm_open.3, sigpause.3, stdin.3, stpcpy.3, strftime.3, strptime.3, syslog.3, towctrans.3, towlower.3, towupper.3, ttyslot.3, ungetwc.3, unlocked_stdio.3, wcpcpy.3, wcpncpy.3, wcrtomb.3, wcscasecmp.3, wcscat.3, wcschr.3, wcscmp.3, wcscpy.3, wcscspn.3, wcsdup.3, wcslen.3, wcsncasecmp.3, wcsncat.3, wcsncmp.3, wcsncpy.3, wcsnlen.3, wcsnrtombs.3, wcspbrk.3, wcsrchr.3, wcsrtombs.3, wcsspn.3, wcsstr.3, wcstok.3, wcstombs.3, wcswidth.3, wctob.3, wctomb.3, wctrans.3, wctype.3, wcwidth.3, wmemchr.3, wmemcmp.3, wmemcpy.3, wmemmove.3, wmemset.3, wprintf.3, console_ioctl.4, pts.4, elf.5, filesystems.5, hosts.5, proc.5, ttytype.5, boot.7, capabilities.7, credentials.7, epoll.7, glob.7, koi8-r.7, path_resolution.7, pty.7, signal.7, suffixes.7, time.7, unicode.7, unix.7, uri.7, utf-8.7: global fix: s/Unix/UNIX/
The man pages were rather inconsistent in the use of "Unix"
versus "UNIX". Let's go with the trademark usage.
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
2010-10-12 04:45:38 +00:00
|
|
|
Its behavior differs noticeably on other flavors of UNIX.
|
2006-03-25 21:28:28 +00:00
|
|
|
In any case, use of
|
2005-10-19 06:54:38 +00:00
|
|
|
.BR ptrace ()
|
2004-11-03 13:51:07 +00:00
|
|
|
is highly OS- and architecture-specific.
|
2007-05-18 16:06:42 +00:00
|
|
|
.SH BUGS
|
2007-06-21 05:38:48 +00:00
|
|
|
On hosts with 2.6 kernel headers,
|
2007-09-20 16:26:31 +00:00
|
|
|
.B PTRACE_SETOPTIONS
|
2007-06-21 05:38:48 +00:00
|
|
|
is declared
|
2007-05-18 16:06:42 +00:00
|
|
|
with a different value than the one for 2.4.
|
|
|
|
This leads to applications compiled with such
|
|
|
|
headers failing when run on 2.4 kernels.
|
2007-06-21 05:38:48 +00:00
|
|
|
This can be worked around by redefining
|
2007-09-20 16:26:31 +00:00
|
|
|
.B PTRACE_SETOPTIONS
|
2007-06-21 05:38:48 +00:00
|
|
|
to
|
|
|
|
.BR PTRACE_OLDSETOPTIONS ,
|
|
|
|
if that is defined.
|
2011-09-24 06:29:34 +00:00
|
|
|
.LP
|
|
|
|
Group-stop notifications are sent to tracer, but not to real parent.
|
|
|
|
Last confirmed on 2.6.38.6.
|
|
|
|
.LP
|
|
|
|
If thread group leader is traced and exits by calling exit syscall,
|
|
|
|
PTRACE_EVENT_EXIT stop will happen for it (if requested), but
|
|
|
|
subsequent WIFEXITED notification will not be delivered until all other
|
|
|
|
threads exit. As explained above, if one of other threads execve's,
|
|
|
|
thread group leader death will *never* be reported. If execve-ed thread
|
|
|
|
is not traced by this tracer, tracer will never know that execve
|
|
|
|
happened.
|
|
|
|
One possible workaround is to detach thread group leader instead of
|
|
|
|
restarting it in this case. Last confirmed on 2.6.38.6.
|
|
|
|
.\" ^^^ need to test/verify this scenario
|
|
|
|
.LP
|
|
|
|
SIGKILL signal may still cause PTRACE_EVENT_EXIT stop before actual
|
|
|
|
signal death. This may be changed in the future - SIGKILL is meant to
|
|
|
|
always immediately kill tasks even under ptrace. Last confirmed on
|
|
|
|
2.6.38.6.
|
2004-11-03 13:51:07 +00:00
|
|
|
.SH "SEE ALSO"
|
|
|
|
.BR gdb (1),
|
|
|
|
.BR strace (1),
|
|
|
|
.BR execve (2),
|
|
|
|
.BR fork (2),
|
|
|
|
.BR signal (2),
|
|
|
|
.BR wait (2),
|
|
|
|
.BR exec (3),
|
|
|
|
.BR capabilities (7)
|