]> git.ipfire.org Git - thirdparty/man-pages.git/blobdiff - man2/ptrace.2
ptrace.2: Document PTRACE_O_SUSPEND_SECCOMP flag
[thirdparty/man-pages.git] / man2 / ptrace.2
index 928ea8920eef18614c53d6b76acf9e5a79bc4214..47c96b1c241d8477e27fadbb0552106732d30455 100644 (file)
@@ -1,5 +1,3 @@
-.\" Hey Emacs! This file is -*- nroff -*- source.
-.\"
 .\" Copyright (c) 1993 Michael Haardt <michael@moria.de>
 .\" Fri Apr  2 11:32:09 MET DST 1993
 .\"
@@ -10,6 +8,7 @@
 .\"
 .\" and Copyright (c) 2011, Denys Vlasenko <vda.linux@googlemail.com>
 .\"
+.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
 .\" 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
@@ -26,9 +25,9 @@
 .\" 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.
+.\" License along with this manual; if not, see
+.\" <http://www.gnu.org/licenses/>.
+.\" %%%LICENSE_END
 .\"
 .\" 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>
 .\"        PTRACE_SETSIGINFO, PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP
 .\"    (Thanks to Blaisorblade, Daniel Jacobowitz and others who helped.)
 .\" 2011-09, major update by Denys Vlasenko <vda.linux@googlemail.com>
+.\" 2015-01, Kees Cook <keescook@chromium.org>
+.\"    Added PTRACE_O_TRACESECCOMP, PTRACE_EVENT_SECCOMP
 .\"
-.\" FIXME (later): Linux 3.1 adds PTRACE_SEIZE, PTRACE_INTERRUPT, and PTRACE_LISTEN.
-.\"
-.TH PTRACE 2 2011-09-26 "Linux" "Linux Programmer's Manual"
+.TH PTRACE 2 2015-07-23 "Linux" "Linux Programmer's Manual"
 .SH NAME
 ptrace \- process trace
 .SH SYNOPSIS
@@ -63,7 +62,7 @@ and examine and change the tracee's memory and registers.
 It is primarily used to implement breakpoint debugging and system
 call tracing.
 .LP
-A tracee first need to be attached to the tracer.
+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
@@ -80,6 +79,12 @@ where
 .I pid
 is the thread ID of the corresponding Linux thread.
 .LP
+(Note that in this page, a "multithreaded process"
+means a thread group consisting of threads created using the
+.BR clone (2)
+.B CLONE_THREAD
+flag.)
+.LP
 A process can initiate a trace by calling
 .BR fork (2)
 and having the resulting child do a
@@ -87,7 +92,9 @@ and having the resulting child do a
 followed (typically) by an
 .BR execve (2).
 Alternatively, one process may commence tracing another process using
-.BR PTRACE_ATTACH .
+.B PTRACE_ATTACH
+or
+.BR PTRACE_SEIZE .
 .LP
 While being traced, the tracee will stop each time a signal is delivered,
 even if the signal is being ignored.
@@ -96,12 +103,26 @@ even if the signal is being ignored.
 which has its usual effect.)
 The tracer will be notified at its next call to
 .BR waitpid (2)
-(or one of the related "wait" system calls)
-and may inspect and modify the tracee while it is stopped.
+(or one of the related "wait" system calls); that call will return a
+.I 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).
 .LP
+If the
+.B PTRACE_O_TRACEEXEC
+option is not in effect, all successful calls to
+.BR execve (2)
+by the traced process will cause it to be sent a
+.B SIGTRAP
+signal,
+giving the parent a chance to gain control before the new program
+begins execution.
+.LP
 When the tracer is finished tracing, it can cause the tracee to continue
 executing in a normal, untraced mode via
 .BR PTRACE_DETACH .
@@ -112,18 +133,6 @@ determines the action to be performed:
 .TP
 .B PTRACE_TRACEME
 Indicate that this process is to be traced by its parent.
-Any signal (except
-.BR SIGKILL )
-delivered to this process will cause it to stop and its
-parent to be notified via
-.BR waitpid (2).
-In addition, all subsequent calls to
-.BR execve (2)
-by the traced process will cause a
-.B SIGTRAP
-to be sent to it,
-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.
 .RI ( pid ,
@@ -131,7 +140,7 @@ isn't expecting to trace it.
 and
 .IR data
 are ignored.)
-.LP
+.IP
 The
 .B PTRACE_TRACEME
 request is used only by the tracee;
@@ -140,6 +149,10 @@ In the following requests,
 .I pid
 specifies the thread ID of the tracee to be acted on.
 For requests other than
+.BR PTRACE_ATTACH ,
+.BR PTRACE_SEIZE ,
+.BR PTRACE_INTERRUPT ,
+and
 .BR PTRACE_KILL ,
 the tracee must be stopped.
 .TP
@@ -152,7 +165,7 @@ call.
 Linux does not have separate text and data address spaces,
 so these two requests are currently equivalent.
 .RI ( data
-is ignored.)
+is ignored; but see NOTES.)
 .TP
 .B PTRACE_PEEKUSER
 .\" PTRACE_PEEKUSR in kernel source, but glibc uses PTRACE_PEEKUSER,
@@ -170,7 +183,7 @@ Typically, the offset must be word-aligned, though this might vary by
 architecture.
 See NOTES.
 .RI ( data
-is ignored.)
+is ignored; but see NOTES.)
 .TP
 .BR PTRACE_POKETEXT ", " PTRACE_POKEDATA
 Copy the word
@@ -179,7 +192,7 @@ to the address
 .I addr
 in the tracee's memory.
 As for
-.BR PTRACE_PEEKTEXT 
+.BR PTRACE_PEEKTEXT
 and
 .BR PTRACE_PEEKDATA ,
 these two requests are currently equivalent.
@@ -198,10 +211,10 @@ the offset must typically be word-aligned.
 In order to maintain the integrity of the kernel,
 some modifications to the USER area are disallowed.
 .\" FIXME In the preceding sentence, which modifications are disallowed,
-.\" and when they are disallowed, how does userspace discover that fact?
+.\" and when they are disallowed, how does user space discover that fact?
 .TP
 .BR PTRACE_GETREGS ", " PTRACE_GETFPREGS
-Copy the tracee's general purpose or floating-point registers,
+Copy the tracee's general-purpose or floating-point registers,
 respectively, to the address
 .I data
 in the tracer.
@@ -210,6 +223,73 @@ See
 for information on the format of this data.
 .RI ( addr
 is ignored.)
+Note that SPARC systems have the meaning of
+.I data
+and
+.I addr
+reversed; that is,
+.I data
+is ignored and the registers are copied to the address
+.IR addr .
+.B PTRACE_GETREGS
+and
+.B PTRACE_GETFPREGS
+are not present on all architectures.
+.TP
+.BR PTRACE_GETREGSET " (since Linux 2.6.34)"
+Read the tracee's registers.
+.I addr
+specifies, in an architecture-dependent way, the type of registers to be read.
+.B 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
+.I addr
+to the corresponding
+.B NT_foo
+constant.
+.I data
+points to a
+.BR "struct iovec" ,
+which describes the destination buffer's location and length.
+On return, the kernel modifies
+.B iov.len
+to indicate the actual number of bytes returned.
+.TP
+.BR PTRACE_SETREGS ", " PTRACE_SETFPREGS
+Modify the tracee's general-purpose or floating-point registers,
+respectively, from the address
+.I data
+in the tracer.
+As for
+.BR PTRACE_POKEUSER ,
+some general-purpose register modifications may be disallowed.
+.\" FIXME . In the preceding sentence, which modifications are disallowed,
+.\" and when they are disallowed, how does user space discover that fact?
+.RI ( addr
+is ignored.)
+Note that SPARC systems have the meaning of
+.I data
+and
+.I addr
+reversed; that is,
+.I data
+is ignored and the registers are copied from the address
+.IR addr .
+.B PTRACE_SETREGS
+and
+.B PTRACE_SETFPREGS
+are not present on all architectures.
+.TP
+.BR PTRACE_SETREGSET " (since Linux 2.6.34)"
+Modify the tracee's registers.
+The meaning of
+.I addr
+and
+.I data
+is analogous to
+.BR PTRACE_GETREGSET .
 .TP
 .BR PTRACE_GETSIGINFO " (since Linux 2.3.99-pre6)"
 Retrieve information about the signal that caused the stop.
@@ -223,19 +303,6 @@ in the tracer.
 .RI ( addr
 is ignored.)
 .TP
-.BR PTRACE_SETREGS ", " PTRACE_SETFPREGS
-Copy the tracee's general purpose or floating-point registers,
-respectively, from the address
-.I data
-in the tracer.
-As for
-.BR PTRACE_POKEUSER ,
-some general purpose register modifications may be disallowed.
-.\" FIXME In the preceding sentence, which modifications are disallowed,
-.\" and when they are disallowed, how does userspace discover that fact?
-.RI ( addr
-is ignored.)
-.TP
 .BR PTRACE_SETSIGINFO " (since Linux 2.3.99-pre6)"
 Set signal information:
 copy a
@@ -252,6 +319,79 @@ itself.
 .RI ( addr
 is ignored.)
 .TP
+.BR PTRACE_PEEKSIGINFO " (since Linux 3.10)"
+.\" commit 84c751bd4aebbaae995fe32279d3dba48327bad4
+Retrieve
+.I siginfo_t
+structures without removing signals from a queue.
+.I addr
+points to a
+.I ptrace_peeksiginfo_args
+structure that specifies the ordinal position from which
+copying of signals should start,
+and the number of signals to copy.
+.I siginfo_t
+structures are copied into the buffer pointed to by
+.IR 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
+.I siginfo
+structures,
+the
+.IR si_code
+field includes information
+.RB ( __SI_CHLD ,
+.BR __SI_FAULT ,
+etc.) that are not otherwise exposed to user space.
+.PP
+.in +10n
+.nf
+struct ptrace_peeksiginfo_args {
+    u64 off;    /* Ordinal position in queue at which
+                   to start copying signals */
+    u32 flags;  /* PTRACE_PEEKSIGINFO_SHARED or 0 */
+    s32 nr;     /* Number of signals to copy */
+};
+.fi
+
+Currently, there is only one flag,
+.BR 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.
+.in
+.PP
+.TP
+.BR PTRACE_GETSIGMASK " (since Linux 3.11)"
+.\" commit 29000caecbe87b6b66f144f72111f0d02fbbf0c1
+Place a copy of the mask of blocked signals (see
+.BR sigprocmask (2))
+in the buffer pointed to by
+.IR data ,
+which should be a pointer to a buffer of type
+.IR sigset_t .
+The
+.I addr
+argument contains the size of the buffer pointed to by
+.IR data
+(i.e.,
+.IR sizeof(sigset_t) ).
+.TP
+.BR PTRACE_SETSIGMASK " (since Linux 3.11)"
+Change the mask of blocked signals (see
+.BR sigprocmask (2))
+to the value specified in the buffer pointed to by
+.IR data ,
+which should be a pointer to a buffer of type
+.IR sigset_t .
+The
+.I addr
+argument contains the size of the buffer pointed to by
+.IR data
+(i.e.,
+.IR sizeof(sigset_t) ).
+.TP
 .BR PTRACE_SETOPTIONS " (since Linux 2.4.6; see BUGS for caveats)"
 Set ptrace options from
 .IR data .
@@ -262,73 +402,35 @@ is interpreted as a bit mask of options,
 which are specified by the following flags:
 .RS
 .TP
-.BR PTRACE_O_TRACESYSGOOD " (since Linux 2.4.6)"
-When delivering system call traps, set bit 7 in the signal number
-(i.e., deliver
-.IR "SIGTRAP|0x80" ).
-This makes it easy for the tracer to distinguish
-normal traps from those caused by a system call.
-.RB ( PTRACE_O_TRACESYSGOOD
-may not work on all architectures.)
-.\" FIXME Please check. In the following paragraphs, I substituted language
-.\" such as:
-.\"     Stop tracee at next fork(2) call with SIGTRAP|PTRACE_EVENT_FORK<<8
-.\" with:
-.\"     Stop tracee at next fork(2) call... A subsequent PTRACE_GETSIGINFO
-.\"     on the stopped tracee will return a siginfo_t structure with si_code
-.\"     set to SIGTRAP|PTRACE_EVENT_FORK<<8.
-.\"
-.\" Is this change correct?
-.\"
-.TP
-.BR PTRACE_O_TRACEFORK " (since Linux 2.5.46)"
-Stop the tracee at the next
-.BR fork (2)
-and automatically start tracing the newly forked process,
-which will start with a
-.BR SIGSTOP .
-A subsequent
-.B PTRACE_GETSIGINFO
-on the stopped tracee will return a
-.I siginfo_t
-structure with
-.I si_code
-set to
-.IR SIGTRAP|PTRACE_EVENT_FORK<<8 .
-The PID of the new process can be retrieved with
-.BR PTRACE_GETEVENTMSG .
-.TP
-.BR PTRACE_O_TRACEVFORK " (since Linux 2.5.46)"
-Stop the tracee at the next
-.BR vfork (2)
-and automatically start tracing the newly vforked process,
-which will start with a
-.BR SIGSTOP .
-A subsequent
-.B PTRACE_GETSIGINFO
-on the stopped tracee will return a
-.I siginfo_t
-structure with
-.I si_code
-set to
-.IR SIGTRAP|PTRACE_EVENT_VFORK<<8 .
-The PID of the new process can be retrieved with
-.BR PTRACE_GETEVENTMSG .
+.BR PTRACE_O_EXITKILL " (since Linux 3.8)"
+.\" commit 992fb6e170639b0849bace8e49bf31bd37c4123
+If a tracer sets this flag, a
+.B SIGKILL
+signal will be sent to every 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.
 .TP
 .BR PTRACE_O_TRACECLONE " (since Linux 2.5.46)"
 Stop the tracee at the next
 .BR clone (2)
 and automatically start tracing the newly cloned process,
 which will start with a
-.BR SIGSTOP .
-A subsequent
-.B PTRACE_GETSIGINFO
-on the stopped tracee will return a
-.I siginfo_t
-structure with
-.I si_code
-set to
-.IR SIGTRAP|PTRACE_EVENT_CLONE<<8 .
+.BR SIGSTOP ,
+or
+.B PTRACE_EVENT_STOP
+if
+.B PTRACE_SEIZE
+was used.
+A
+.BR waitpid (2)
+by the tracer will return a
+.I status
+value such that
+
+.nf
+  status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8))
+.fi
+
 The PID of the new process can be retrieved with
 .BR PTRACE_GETEVENTMSG .
 .IP
@@ -356,39 +458,33 @@ is set.
 .BR PTRACE_O_TRACEEXEC " (since Linux 2.5.46)"
 Stop the tracee at the next
 .BR execve (2).
-A subsequent
-.B PTRACE_GETSIGINFO
-on the stopped tracee will return a
-.I siginfo_t
-structure with
-.I si_code
-set to
-.IR SIGTRAP|PTRACE_EVENT_EXEC<<8 .
-.TP
-.BR PTRACE_O_TRACEVFORKDONE " (since Linux 2.5.60)"
-Stop the tracee at the completion of the next
-.BR vfork (2).
-A subsequent
-.B PTRACE_GETSIGINFO
-on the stopped tracee will return a
-.I siginfo_t
-structure with
-.I si_code
-set to
-.IR SIGTRAP|PTRACE_EVENT_VFORK_DONE<<8 .
-The PID of the new process can (since Linux 2.6.18) be retrieved with
+A
+.BR waitpid (2)
+by the tracer will return a
+.I status
+value such that
+
+.nf
+  status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))
+.fi
+
+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
 .BR PTRACE_GETEVENTMSG .
 .TP
 .BR PTRACE_O_TRACEEXIT " (since Linux 2.5.60)"
 Stop the tracee at exit.
-A subsequent
-.B PTRACE_GETSIGINFO
-on the stopped tracee will return a
-.I siginfo_t
-structure with
-.I si_code
-set to
-.IR SIGTRAP|PTRACE_EVENT_EXIT<<8 .
+A
+.BR waitpid (2)
+by the tracer will return a
+.I status
+value such that
+
+.nf
+  status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))
+.fi
+
 The tracee's exit status can be retrieved with
 .BR PTRACE_GETEVENTMSG .
 .IP
@@ -399,6 +495,115 @@ 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.
+.TP
+.BR PTRACE_O_TRACEFORK " (since Linux 2.5.46)"
+Stop the tracee at the next
+.BR fork (2)
+and automatically start tracing the newly forked process,
+which will start with a
+.BR SIGSTOP ,
+or
+.B PTRACE_EVENT_STOP
+if
+.B PTRACE_SEIZE
+was used.
+A
+.BR waitpid (2)
+by the tracer will return a
+.I status
+value such that
+
+.nf
+  status>>8 == (SIGTRAP | (PTRACE_EVENT_FORK<<8))
+.fi
+
+The PID of the new process can be retrieved with
+.BR PTRACE_GETEVENTMSG .
+.TP
+.BR PTRACE_O_TRACESYSGOOD " (since Linux 2.4.6)"
+When delivering system call traps, set bit 7 in the signal number
+(i.e., deliver
+.IR "SIGTRAP|0x80" ).
+This makes it easy for the tracer to distinguish
+normal traps from those caused by a system call.
+.RB ( PTRACE_O_TRACESYSGOOD
+may not work on all architectures.)
+.TP
+.BR PTRACE_O_TRACEVFORK " (since Linux 2.5.46)"
+Stop the tracee at the next
+.BR vfork (2)
+and automatically start tracing the newly vforked process,
+which will start with a
+.BR SIGSTOP ,
+or
+.B PTRACE_EVENT_STOP
+if
+.B PTRACE_SEIZE
+was used.
+A
+.BR waitpid (2)
+by the tracer will return a
+.I status
+value such that
+
+.nf
+  status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK<<8))
+.fi
+
+The PID of the new process can be retrieved with
+.BR PTRACE_GETEVENTMSG .
+.TP
+.BR PTRACE_O_TRACEVFORKDONE " (since Linux 2.5.60)"
+Stop the tracee at the completion of the next
+.BR vfork (2).
+A
+.BR waitpid (2)
+by the tracer will return a
+.I status
+value such that
+
+.nf
+  status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK_DONE<<8))
+.fi
+
+The PID of the new process can (since Linux 2.6.18) be retrieved with
+.BR PTRACE_GETEVENTMSG .
+.TP
+.BR PTRACE_O_TRACESECCOMP " (since Linux 3.5)"
+Stop the tracee when a
+.BR seccomp (2)
+.BR SECCOMP_RET_TRACE
+rule is triggered.
+A
+.BR waitpid (2)
+by the tracer will return a
+.I status
+value such that
+
+.nf
+  status>>8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP<<8))
+.fi
+
+While this triggers a
+.BR PTRACE_EVENT
+stop, it is similar to a syscall-enter-stop, in that the tracee has
+not yet entered the syscall that seccomp triggered on.
+The seccomp event message data (from the
+.BR SECCOMP_RET_DATA
+portion of the seccomp filter rule) can be retrieved with
+.BR PTRACE_GETEVENTMSG .
+.TP
+.BR PTRACE_O_SUSPEND_SECCOMP " (since Linux 4.2)"
+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 usecase 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
+.BR CAP_SYS_ADMIN ,
+not have any seccomp protections installed, and not have
+.BR PTRACE_O_SUSPEND_SECCOMP
+set on itself.
 .RE
 .TP
 .BR PTRACE_GETEVENTMSG " (since Linux 2.5.46)"
@@ -418,7 +623,14 @@ For
 and
 .BR PTRACE_EVENT_CLONE ,
 this is the PID of the new process.
-.RI (  addr
+For
+.BR PTRACE_EVENT_SECCOMP ,
+this is the
+.BR seccomp (2)
+filter's
+.BR SECCOMP_RET_DATA
+associated with the triggered rule.
+.RI ( addr
 is ignored.)
 .TP
 .B PTRACE_CONT
@@ -454,7 +666,7 @@ The
 .I data
 argument is treated as for
 .BR PTRACE_CONT .
-.RI (addr
+.RI ( addr
 is ignored.)
 .TP
 .BR PTRACE_SYSEMU ", " PTRACE_SYSEMU_SINGLESTEP " (since Linux 2.6.14)"
@@ -471,9 +683,23 @@ The
 .I data
 argument is treated as for
 .BR PTRACE_CONT .
-.RI ( addr
-is ignored;
-not supported on all architectures.)
+The
+.I addr
+argument is ignored.
+These requests are currently
+.\" As at 3.7
+supported only on x86.
+.TP
+.BR 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
+.B SIGSTOP
+(or other stopping signal).
+See the "group-stop" subsection for additional information.
+.B PTRACE_LISTEN
+works only on tracees attached by
+.BR PTRACE_SEIZE .
 .TP
 .B PTRACE_KILL
 Send the tracee a
@@ -499,20 +725,45 @@ otherwise it may not work
 By contrast, sending a
 .B SIGKILL
 directly has no such limitation.
-.\" mtk: Commented out the following. It doesn't belong in the man page.
-.\" .LP
-.\" [Note: deprecation suggested by Oleg Nesterov. He prefers to deprecate
-.\" it instead of describing (and needing to support) PTRACE_KILL's quirks.]
+.\" [Note from Denys Vlasenko:
+.\"     deprecation suggested by Oleg Nesterov. He prefers to deprecate it
+.\"     instead of describing (and needing to support) PTRACE_KILL's quirks.]
+.TP
+.BR PTRACE_INTERRUPT " (since Linux 3.4)"
+Stop a tracee.
+If the tracee is running or sleeping in kernel space and
+.B PTRACE_SYSCALL
+is 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 and
+.B PTRACE_LISTEN
+was sent to it,
+the tracee stops with
+.B PTRACE_EVENT_STOP
+and
+.I 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 with
+.B PTRACE_EVENT_STOP
+with
+.I WSTOPSIG(status)
+==
+.BR SIGTRAP .
+.B PTRACE_INTERRUPT
+only works on tracees attached by
+.BR PTRACE_SEIZE .
 .TP
 .B PTRACE_ATTACH
 Attach to the process specified in
 .IR pid ,
 making it a tracee of the calling process.
-.\" FIXME So, was the following EVER true? IF it was,
-.\"       we should reinstate the text and add mention of
-.\"       the kernel version where the behaviour changed.
-.\"
-.\" Not true: (removed by dv)
+.\" No longer true (removed by Denys Vlasenko, 2011, who remarks:
+.\"        "I think it isn't true in non-ancient 2.4 and in 2.6/3.x.
+.\"         Basically, it's not true for any Linux in practical use.
 .\" ; 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
@@ -534,6 +785,49 @@ and
 .I data
 are ignored.)
 .TP
+.BR PTRACE_SEIZE " (since Linux 3.4)"
+Attach to the process specified in
+.IR pid ,
+making it a tracee of the calling process.
+Unlike
+.BR PTRACE_ATTACH ,
+.B PTRACE_SEIZE
+does not stop the process.
+Group-stops are reported as
+.B PTRACE_EVENT_STOP
+and
+.I WSTOPSIG(status)
+returns the stop signal.
+Automatically attached children stop with
+.B PTRACE_EVENT_STOP
+and
+.I WSTOPSIG(status)
+returns
+.B SIGTRAP
+instead of having
+.B SIGSTOP
+signal delivered to them.
+.BR evecve (2)
+does not deliver an extra
+.BR SIGTRAP .
+Only a
+.BR PTRACE_SEIZE d
+process can accept
+.B PTRACE_INTERRUPT
+and
+.B PTRACE_LISTEN
+commands.
+The "seized" behavior just described is inherited by
+children that are automatically attached using
+.BR PTRACE_O_TRACEFORK ,
+.BR PTRACE_O_TRACEVFORK ,
+and
+.BR PTRACE_O_TRACECLONE .
+.I addr
+must be zero.
+.I data
+contains a bit mask of ptrace options to activate immediately.
+.TP
 .B PTRACE_DETACH
 Restart the stopped tracee as for
 .BR PTRACE_CONT ,
@@ -542,13 +836,6 @@ Under Linux, a tracee can be detached in this way regardless
 of which method was used to initiate tracing.
 .RI ( addr
 is ignored.)
-.\"
-.\" 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 multithreaded) process receives a killing signal
 (one whose disposition is set to
@@ -569,10 +856,8 @@ tracees within a multithreaded process.
 (The term "signal-delivery-stop" is explained below.)
 .LP
 .B SIGKILL
-operates similarly, with exceptions.
-No signal-delivery-stop is generated for
-.B SIGKILL
-and therefore the tracer can't suppress it.
+does not generate signal-delivery-stop and
+therefore the tracer can't suppress it.
 .B SIGKILL
 kills even within system calls
 (syscall-exit-stop is not generated prior to death by
@@ -600,7 +885,8 @@ This applies to exits via
 .BR exit (2),
 .BR exit_group (2),
 and signal deaths (except
-.BR SIGKILL ),
+.BR SIGKILL ,
+depending on the kernel version; see BUGS below),
 and when threads are torn down on
 .BR execve (2)
 in a multithreaded process.
@@ -608,7 +894,7 @@ in a multithreaded process.
 The tracer cannot assume that the ptrace-stopped tracee exists.
 There are many scenarios when the tracee may die while stopped (such as
 .BR SIGKILL ).
-Therefore, the tracer must be prepared to handle an 
+Therefore, the tracer must be prepared to handle an
 .B ESRCH
 error on any ptrace operation.
 Unfortunately, the same error is returned if the tracee
@@ -635,15 +921,36 @@ The tracer can't assume that the tracee
 ends its life by reporting
 .I WIFEXITED(status)
 or
-.IR WIFSIGNALED(status) .
-.LP
-.\"     or can it? Do we include such a promise into ptrace API?
-.\"
-.\" FIXME: The preceding comment seems to be unresolved?
-.\"        Do you want to add anything?
-.\"
+.IR WIFSIGNALED(status) ;
+there are cases where this does not occur.
+For example, if a thread other than thread group leader does an
+.BR execve (2),
+it disappears;
+its PID will never be seen again,
+and any subsequent ptrace stops will be reported under
+the thread group leader's PID.
 .SS Stopped states
 A tracee can be in two states: running or stopped.
+For the purposes of ptrace, a tracee which is blocked in a system call
+(such as
+.BR read (2),
+.BR pause (2),
+etc.)
+is nevertheless considered to be running, even if the tracee is blocked
+for a long time.
+The state of the tracee after
+.BR PTRACE_LISTEN
+is somewhat of a gray area: it is not in any ptrace-stop (ptrace commands
+won't work on it, and it will deliver
+.BR waitpid (2)
+notifications),
+but it also may be considered "stopped" because
+it is not executing instructions (is not scheduled), and if it was
+in group-stop before
+.BR PTRACE_LISTEN ,
+it will not respond to signals until
+.B SIGCONT
+is received.
 .LP
 There are many kinds of states when the tracee is stopped, and in ptrace
 discussions they are often conflated.
@@ -672,16 +979,13 @@ Ptrace-stopped tracees are reported as returns with
 greater than 0 and
 .I WIFSTOPPED(status)
 true.
-.LP
-.\" FIXME: mtk: the following comment seems to be unresolved?
-.\"        Do you want to add anything?
-.\"
-.\"     Do we require __WALL usage, or will just using 0 be ok? Are the
+.\" Denys Vlasenko:
+.\"     Do we require __WALL usage, or will just using 0 be ok? (With 0,
+.\"     I am not 100% sure there aren't ugly corner cases.) Are the
 .\"     rules different if user wants to use waitid? Will waitid require
 .\"     WEXITED?
 .\"
 .LP
-.\" FIXME: Is the following comment "__WALL... implies" true?
 The
 .B __WALL
 flag does not include the
@@ -706,23 +1010,22 @@ even if the tracer knows there should be a notification.
 Example:
 .nf
 
-    kill(tracee, SIGKILL);
-    waitpid(tracee, &status, __WALL | WNOHANG);
+    errno = 0;
+    ptrace(PTRACE_CONT, pid, 0L, 0L);
+    if (errno == ESRCH) {
+        /* tracee is dead */
+        r = waitpid(tracee, &status, __WALL | WNOHANG);
+        /* r can still be 0 here! */
+    }
 .fi
-.\" FIXME: mtk: the following comment seems to be unresolved?
-.\"        Do you want to add anything?
-.\"
+.\" FIXME .
 .\"     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
-.\"
-.\" FIXME: mtk: the following text appears to be incomplete.
-.\"        Do you want to add anything?
-.\"
-[, PTRACE_SINGLESTEP, PTRACE_SYSEMU,
-PTRACE_SYSEMU_SINGLESTEP].
+group-stops,
+.B PTRACE_EVENT
+stops, syscall-stops.
 They all are reported by
 .BR waitpid (2)
 with
@@ -732,14 +1035,11 @@ They may be differentiated by examining the value
 .IR status>>8 ,
 and if there is ambiguity in that value, by querying
 .BR PTRACE_GETSIGINFO .
-.\"
-.\" FIXME What is the purpose of the following sentence? Is it to warn
-.\"       the reader not to use WSTOPSIG()? If so, we should make that
-.\"       point more explicitly.
 (Note: the
 .I WSTOPSIG(status)
-macro returns the value
-.IR "(status>>8)\ &\ 0xff)" .)
+macro can't be used to perform this examination,
+because it returns the value
+.IR "(status>>8)\ &\ 0xff" .)
 .SS Signal-delivery-stop
 When a (possibly multithreaded) process receives any signal except
 .BR SIGKILL ,
@@ -751,8 +1051,6 @@ If the selected thread is traced, it enters signal-delivery-stop.
 At this point, the signal is not yet delivered to the process,
 and can be suppressed by the tracer.
 If the tracer doesn't suppress the signal,
-.\"
-.\" FIXME: I added the word "restart" to the following line. Okay?
 it passes the signal to the tracee in the next ptrace restart request.
 This second step of signal delivery is called
 .I "signal injection"
@@ -767,9 +1065,9 @@ Signal-delivery-stop is observed by the tracer as
 .BR waitpid (2)
 returning with
 .I WIFSTOPPED(status)
-true, with the stopping signal returned by
+true, with the signal returned by
 .IR WSTOPSIG(status) .
-If the stopping signal is
+If the signal is
 .BR SIGTRAP ,
 this may be a different kind of ptrace-stop;
 see the "Syscall-stops" and "execve" sections below for details.
@@ -795,7 +1093,7 @@ This operation is called
 .I "signal injection"
 in this manual page, to distinguish it from signal-delivery-stop.
 .LP
-Note that the
+The
 .I sig
 value may be different from the
 .I WSTOPSIG(status)
@@ -803,16 +1101,21 @@ value: the tracer can cause a different signal to be injected.
 .LP
 Note that a suppressed signal still causes system calls to return
 prematurely.
-Restartable system calls will be restarted (the tracer will
-observe the tracee to execute
-.BR restart_syscall(2)
-if the tracer uses
-.BR PTRACE_SYSCALL );
-non-restartable system calls may fail with
+In this case, system calls will be restarted: the tracer will
+observe the tracee to reexecute the interrupted system call (or
+.BR restart_syscall (2)
+system call for a few system calls which use a different mechanism
+for restarting) if the tracer uses
+.BR PTRACE_SYSCALL .
+Even system calls (such as
+.BR poll (2))
+which are not restartable after signal are restarted after
+signal is suppressed;
+however, kernel bugs exist which cause some system calls to fail with
 .B EINTR
 even though no observable signal is injected to the tracee.
 .LP
-Note that restarting ptrace commands issued in ptrace-stops other than
+Restarting ptrace commands issued in ptrace-stops other than
 signal-delivery-stop are not guaranteed to inject a signal, even if
 .I sig
 is nonzero.
@@ -823,14 +1126,14 @@ Ptrace users should not try to "create a new signal" this way: use
 .BR tgkill (2)
 instead.
 .LP
-.\"
-.\" FIXME: the referrent of "This" in the next line is not clear.
-.\"        What does "This" refer to?
-This is a cause of confusion among ptrace users.
+The fact that signal injection requests may be ignored
+when restarting the tracee after
+ptrace stops that are not signal-delivery-stops
+is a cause of confusion among ptrace users.
 One typical scenario is that the tracer observes group-stop,
 mistakes it for signal-delivery-stop, restarts the tracee with
 
-    ptrace(PTRACE_rest, pid, 0, stopsig)
+    ptrace(PTRACE_restart, pid, 0, stopsig)
 
 with the intention of injecting
 .IR stopsig ,
@@ -843,7 +1146,7 @@ The
 signal has a side effect of waking up (all threads of)
 a group-stopped process.
 This side effect happens before signal-delivery-stop.
-The tracer can't suppress this side-effect (it can
+The tracer can't suppress this side effect (it can
 only suppress signal injection, which only causes the
 .BR SIGCONT
 handler to not be executed in the tracee, if such a handler is installed).
@@ -862,6 +1165,16 @@ Stopping signals cause (all threads of) a process to enter group-stop.
 This side effect happens after signal injection, and therefore can be
 suppressed by the tracer.
 .LP
+In Linux 2.4 and earlier, the
+.B SIGSTOP
+signal can't be injected.
+.\" In the Linux 2.4 sources, in arch/i386/kernel/signal.c::do_signal(),
+.\" there is:
+.\"
+.\"             /* The debugger continued.  Ignore SIGSTOP.  */
+.\"             if (signr == SIGSTOP)
+.\"                     continue;
+.LP
 .B PTRACE_GETSIGINFO
 can be used to retrieve a
 .I siginfo_t
@@ -923,7 +1236,17 @@ then it is definitely a group-stop.
 .B SIGKILL
 killed the tracee.)
 .LP
-As of kernel 2.6.38,
+If tracee was attached using
+.BR PTRACE_SEIZE ,
+group-stop is indicated by
+.BR PTRACE_EVENT_STOP :
+.IR "status>>16 == PTRACE_EVENT_STOP" .
+This allows detection of group-stops
+without requiring an extra
+.B PTRACE_GETSIGINFO
+call.
+.LP
+As of Linux 2.6.38,
 after the tracer sees the tracee ptrace-stop and until it
 restarts or kills it, the tracee will not run,
 and will not send notifications (except
@@ -932,21 +1255,30 @@ death) to the tracer, even if the tracer enters into another
 .BR waitpid (2)
 call.
 .LP
-.\"
-.\" FIXME ??? referrent of "it" in the next line is unclear
-.\"        What does "it" refer to?
-Currently, it causes a problem with transparent handling of stopping
-signals: if the tracer restarts the tracee after group-stop,
-.B SIGSTOP
-is effectively ignored: the tracee doesn't remain stopped, it runs.
+The kernel behavior described in the previous paragraph
+causes a problem with transparent handling of stopping signals.
+If the tracer restarts the tracee after group-stop,
+the stopping signal
+is effectively ignored\(emthe tracee doesn't remain stopped, it runs.
 If the tracer doesn't restart the tracee before entering into the next
 .BR waitpid (2),
 future
 .B SIGCONT
-signals will not be reported to the tracer.
-This would cause
+signals will not be reported to the tracer;
+this would cause the
 .B SIGCONT
-to have no effect.
+signals to have no effect on the tracee.
+.LP
+Since Linux 3.4, there is a method to overcome this problem: instead of
+.BR PTRACE_CONT ,
+a
+.B PTRACE_LISTEN
+command can be used to restart a tracee in a way where it does not execute,
+but waits for a new event which it can report via
+.BR waitpid (2)
+(such as when
+it is restarted by a
+.BR SIGCONT ).
 .SS PTRACE_EVENT stops
 If the tracer sets
 .B PTRACE_O_TRACE_*
@@ -995,7 +1327,7 @@ with the exit signal set to
 .TP
 .B PTRACE_EVENT_CLONE
 Stop before return from
-.BR clone (2)
+.BR clone (2).
 .TP
 .B PTRACE_EVENT_VFORK_DONE
 Stop before return from
@@ -1016,6 +1348,9 @@ can be used to retrieve the new thread's ID.
 .B PTRACE_EVENT_EXEC
 Stop before return from
 .BR execve (2).
+Since Linux 3.0,
+.BR PTRACE_GETEVENTMSG
+returns the former thread ID.
 .TP
 .B PTRACE_EVENT_EXIT
 Stop before exit (including death from
@@ -1032,12 +1367,31 @@ The tracee is still alive; it needs to be
 or
 .BR PTRACE_DETACH ed
 to finish exiting.
+.TP
+.B PTRACE_EVENT_STOP
+Stop induced by
+.B PTRACE_INTERRUPT
+command, or group-stop, or initial ptrace-stop when a new child is attached
+(only if attached using
+.BR PTRACE_SEIZE ).
+.TP
+.B PTRACE_EVENT_SECCOMP
+Stop triggered by a
+.BR seccomp (2)
+rule on tracee syscall entry when
+.BR PTRACE_O_TRACESECCOMP
+has been set by the tracer.
+The seccomp event message data (from the
+.BR SECCOMP_RET_DATA
+portion of the seccomp filter rule) can be retrieved with
+.BR PTRACE_GETEVENTMSG .
 .LP
 .B PTRACE_GETSIGINFO
 on
 .B PTRACE_EVENT
 stops returns
-.B SIGTRAP in
+.B SIGTRAP
+in
 .IR si_signo ,
 with
 .I si_code
@@ -1094,13 +1448,15 @@ for the following cases:
 .TP
 .IR si_code " <= 0"
 .B SIGTRAP
-.\" FIXME: Please confirm this is okay: I changed
-.\"        "the usual suspects" to "by a system call". Okay?
-.\"        Shouldn't we also add kill(2) here?
-was sent by a system call
+was delivered as a result of a user-space action,
+for example, a system call
 .RB ( tgkill (2),
+.BR kill (2),
 .BR sigqueue (3),
-etc.)
+etc.),
+expiration of a POSIX timer,
+change of state on a POSIX message queue,
+or completion of an asynchronous I/O request.
 .TP
 .IR si_code " == SI_KERNEL (0x80)"
 .B SIGTRAP
@@ -1114,9 +1470,6 @@ and performing
 .B PTRACE_GETSIGINFO
 for every syscall-stop may be somewhat expensive.
 .LP
-.\"
-.\" FIXME referrent of "them" in next line ???
-.\"       What does "them" refer to?
 Some architectures allow the cases to be distinguished
 by examining registers.
 For example, on x86,
@@ -1142,9 +1495,8 @@ But such detection is fragile and is best avoided.
 .LP
 Using the
 .B PTRACE_O_TRACESYSGOOD
-.\"
-.\" FIXME Below: "is the recommended method" for WHAT?
-option is the recommended method,
+option is the recommended method to distinguish syscall-stops
+from other kinds of ptrace-stops,
 since it is reliable and does not incur a performance penalty.
 .LP
 Syscall-enter-stop and syscall-exit-stop are
@@ -1175,16 +1527,17 @@ set to
 or
 .IR (SIGTRAP|0x80) .
 .SS PTRACE_SINGLESTEP, PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP stops
+[Details of these kinds of stops are yet to be documented.]
 .\"
-.\" FIXME The following TODO is unresolved
-.\"       Do you want to add anything?
-.\"
-(TODO: document stops occurring with PTRACE_SINGLESTEP, PTRACE_SYSEMU,
-PTRACE_SYSEMU_SINGLESTEP)
+.\" FIXME .
+.\" document stops occurring with PTRACE_SINGLESTEP, PTRACE_SYSEMU,
+.\" PTRACE_SYSEMU_SINGLESTEP
 .SS Informational and restarting ptrace commands
 Most ptrace commands (all except
 .BR PTRACE_ATTACH ,
+.BR PTRACE_SEIZE ,
 .BR PTRACE_TRACEME ,
+.BR PTRACE_INTERRUPT ,
 and
 .BR PTRACE_KILL )
 require the tracee to be in a ptrace-stop, otherwise they fail with
@@ -1200,6 +1553,8 @@ These commands leave the tracee in ptrace-stopped state:
     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_GETREGSET, pid, NT_foo, &iov);
+    ptrace(PTRACE_SETREGSET, pid, NT_foo, &iov);
     ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo);
     ptrace(PTRACE_SETSIGINFO, pid, 0, &siginfo);
     ptrace(PTRACE_GETEVENTMSG, pid, 0, &long_var);
@@ -1220,7 +1575,7 @@ is not documented as returning a meaningful event message.
 The call
 
     ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags);
-    
+
 affects one tracee.
 The tracee's current flags are replaced.
 Flags are inherited by new tracees created and "auto-attached" via active
@@ -1233,31 +1588,39 @@ options.
 Another group of commands makes the ptrace-stopped tracee run.
 They have the form:
 .LP
-    ptrace(PTRACE_cmd, pid, 0, sig);
+    ptrace(cmd, pid, 0, sig);
 .LP
 where
 .I cmd
 is
 .BR PTRACE_CONT ,
+.BR PTRACE_LISTEN ,
 .BR PTRACE_DETACH ,
 .BR PTRACE_SYSCALL ,
 .BR PTRACE_SINGLESTEP ,
 .BR PTRACE_SYSEMU ,
 or
-.BR PTRACE_SYSEMU_SINGLESTEP.
+.BR PTRACE_SYSEMU_SINGLESTEP .
 If the tracee is in signal-delivery-stop,
 .I sig
 is the signal to be injected (if it is nonzero).
 Otherwise,
 .I sig
 may be ignored.
-(Recommended practice is to always pass 0 in these cases.)
+(When restarting a tracee from a ptrace-stop other than signal-delivery-stop,
+recommended practice is to always pass 0 in
+.IR sig .)
 .SS Attaching and detaching
 A thread can be attached to the tracer using the call
 
     ptrace(PTRACE_ATTACH, pid, 0, 0);
 
-This also sends
+or
+
+    ptrace(PTRACE_SEIZE, pid, 0, PTRACE_O_flags);
+
+.B PTRACE_ATTACH
+sends
 .B SIGSTOP
 to this thread.
 If the tracer wants this
@@ -1272,26 +1635,32 @@ The usual practice is to reinject these signals until
 is seen, then suppress
 .B SIGSTOP
 injection.
-.\"
-.\" FIXME I significantly rewrote the following sentence to try to make it
-.\" clearer. Is the meaning still preserved?
 The design bug here is that a ptrace attach and a concurrently delivered
 .B SIGSTOP
 may race and the concurrent
 .B SIGSTOP
 may be lost.
 .\"
-.\" FIXME: mtk: the following comment seems to be unresolved?
-.\"       Do you want to add any text?
-.\"
-.\"      Describe how to attach to a thread which is already group-stopped.
+.\" FIXME . Describe how to attach to a thread which is already group-stopped.
 .LP
 Since attaching sends
 .B SIGSTOP
 and the tracer usually suppresses it, this may cause a stray
-.I EINTR
+.B EINTR
 return from the currently executing system call in the tracee,
-as described in the "signal injection and suppression" section.
+as described in the "Signal injection and suppression" section.
+.LP
+Since Linux 3.4,
+.B PTRACE_SEIZE
+can be used instead of
+.BR PTRACE_ATTACH .
+.B PTRACE_SEIZE
+does not stop the attached process.
+If you need to stop
+it after attach (or at any other time) without sending it any signals,
+use
+.B PTRACE_INTERRUPT
+command.
 .LP
 The request
 
@@ -1308,7 +1677,7 @@ with
 and allow the parent (which is our tracer now) to observe our
 signal-delivery-stop.
 .LP
-If the 
+If the
 .BR PTRACE_O_TRACEFORK ,
 .BR PTRACE_O_TRACEVFORK ,
 or
@@ -1365,79 +1734,45 @@ Yet another complication is to be sure that
 the tracee is not already ptrace-stopped,
 because no signal delivery happens while it is\(emnot even
 .BR SIGSTOP .
-.\" FIXME: mtk: the following comment seems to be unresolved?
-.\"       Do you want to add anything?
-.\"
-.\"     Describe how to detach from a group-stopped tracee so that it
-.\"     doesn't run, but continues to wait for SIGCONT.
-.\"
+.\" FIXME . Describe how to detach from a group-stopped tracee so that it
+.\"        doesn't run, but continues to wait for SIGCONT.
 .LP
 If the tracer dies, all tracees are automatically detached and restarted,
 unless they were in group-stop.
-Handling of restart from group-stop is
-.\" FIXME: Define currently
-currently buggy, but the
-.\" FIXME: Planned for when?
-"as planned" behavior is to leave tracee stopped and waiting for
+Handling of restart from group-stop is currently buggy,
+but the "as planned" behavior is to leave tracee stopped and waiting for
 .BR SIGCONT .
 If the tracee is restarted from signal-delivery-stop,
 the pending signal is injected.
 .SS execve(2) under ptrace
-.\" clone(2) THREAD_CLONE says:
+.\" clone(2) CLONE_THREAD says:
 .\"     If  any  of the threads in a thread group performs an execve(2),
 .\"     then all threads other than the thread group leader are terminated,
-.\"     and the new program is executed in the thread group leader.  
-.\"
-.\" FIXME mtk-addition:  please check: I added the following piece to
-.\"       clarify that multithreaded here means clone()+CLONE_THREAD
-.\"
-When one thread in a multithreaded process
-(i.e., a thread group consisting of threads created using the
-.BR clone (2)
-.B CLONE_THREAD
-flag) calls
-.\" FIXME end-mtk-addition
+.\"     and the new program is executed in the thread group leader.
 .\"
+When one thread in a multithreaded process calls
 .BR execve (2),
 the kernel destroys all other threads in the process,
 .\" In kernel 3.1 sources, see fs/exec.c::de_thread()
 and resets the thread ID of the execing thread to the
 thread group ID (process ID).
-.\"
-.\" FIXME mtk-addition:  please check: I added the following piece:
 (Or, to put things another way, when a multithreaded process does an
 .BR execve (2),
-the kernel makes it look as though the
+at completion of the call, it appears as though the
 .BR execve (2)
 occurred in the thread group leader, regardless of which thread did the
 .BR execve (2).)
-.\" FIXME end-mtk-addition
-.\"
 This resetting of the thread ID looks very confusing to tracers:
 .IP * 3
 All other threads stop in
-.\" FIXME: mtk: What is "PTRACE_EXIT stop"?
-.\"        Should that be "PTRACE_EVENT_EXIT stop"?
-.B PTRACE_EXIT
-stop,
-.\" FIXME: mtk: In the next line, "by active ptrace option" is unclear.
-.\"        What does it mean?
-if requested by active ptrace option.
+.B PTRACE_EVENT_EXIT
+stop, if the
+.BR PTRACE_O_TRACEEXIT
+option was turned on.
 Then all other threads except the thread group leader report
 death as if they exited via
 .BR _exit (2)
 with exit code 0.
-Then
-.B PTRACE_EVENT_EXEC
-.\" FIXME: mtk: In the next line, "by active ptrace option" is unclear
-.\"        What does it mean?
-stop happens, if requested by active ptrace option.
-.\" FIXME: mtk: the following comment seems to be unresolved?
-.\"       (on which tracee - leader? execve-ing one?)
-.\" 
-.\" FIXME: Please check: at various places in the following,
-.\"        I have changed "pid" to "[the tracee's] thead ID"
-.\"        Is that okay?
 .IP *
 The execing tracee changes its thread ID while it is in the
 .BR execve (2).
@@ -1447,9 +1782,22 @@ or fed into ptrace calls, is the tracee's thread ID.)
 That is, the tracee's thread ID is reset to be the same as its process ID,
 which is the same as the thread group leader's thread ID.
 .IP *
-If the thread group leader has reported its death by this time,
+Then a
+.B PTRACE_EVENT_EXEC
+stop happens, if the
+.BR PTRACE_O_TRACEEXEC
+option was turned on.
+.IP *
+If the thread group leader has reported its
+.B PTRACE_EVENT_EXIT
+stop by this time,
 it appears to the tracer that
 the dead thread leader "reappears from nowhere".
+(Note: the thread group leader does not report death via
+.I WIFEXITED(status)
+until there is at least one other live thread.
+This eliminates the possibility that the tracer will see
+it dying and then reappearing.)
 If the thread group leader was still alive,
 for the tracer this may look as if thread group leader
 returns from a different system call than it entered,
@@ -1467,18 +1815,22 @@ the thread ID change in the tracee.
 The
 .B PTRACE_O_TRACEEXEC
 option is the recommended tool for dealing with this situation.
-It enables
-.B PTRACE_EVENT_EXEC
-stop, which occurs before
+First, it enables
+.BR PTRACE_EVENT_EXEC
+stop,
+which occurs before
 .BR execve (2)
 returns.
-.\" FIXME Following on from the previous sentences,
-.\"       can/should we add a few more words on how
-.\"       PTRACE_EVENT_EXEC stop helps us deal with this situation?
-.LP
-The thread ID change happens before
-.B PTRACE_EVENT_EXEC
-stop, not after.
+In this stop, the tracer can use
+.B PTRACE_GETEVENTMSG
+to retrieve the tracee's former thread ID.
+(This feature was introduced in Linux 3.0.)
+Second, the
+.B PTRACE_O_TRACEEXEC
+option disables legacy
+.B SIGTRAP
+generation on
+.BR execve (2).
 .LP
 When the tracer receives
 .B PTRACE_EVENT_EXEC
@@ -1494,23 +1846,17 @@ data structures describing the threads of this process,
 and retain only one data structure\(emone which
 describes the single still running tracee, with
 
-    thread ID == thread group ID == process id.
-.LP
-Currently, there is no way to retrieve the former
-thread ID of the execing tracee.
-If the tracer doesn't keep track of its tracees' thread group relations,
-it may be unable to know which tracee execed and therefore no longer
-exists under the old thread ID due to a thread ID change.
+    thread ID == thread group ID == process ID.
 .LP
 Example: two threads call
 .BR execve (2)
 at the same time:
 .LP
 .nf
-*** we get syscall-entry-stop in thread 1: **
+*** we get syscall-enter-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: **
+*** we get syscall-enter-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 **
@@ -1518,15 +1864,16 @@ PID2 execve("/bin/bar", "bar" <unfinished ...>
 PID0 <... execve resumed> )             = 0
 .fi
 .LP
-In this situation, there is no way to know which
-.BR execve (2)
-succeeded.
-.LP
 If the
 .B PTRACE_O_TRACEEXEC
 option is
 .I not
-in effect for the execing tracee, the kernel delivers an extra
+in effect for the execing tracee,
+and if the tracee was
+.BR PTRACE_ATTACH ed
+rather that
+.BR PTRACE_SEIZE d,
+the kernel delivers an extra
 .B SIGTRAP
 to the tracee after
 .BR execve (2)
@@ -1553,13 +1900,15 @@ signal to the user, and would suppress its delivery to the tracee (if
 is set to
 .BR SIG_DFL ,
 it is a killing signal).
-However, determining 
+However, determining
 .I which
 .B SIGTRAP
 to suppress is not easy.
 Setting the
 .B PTRACE_O_TRACEEXEC
-option and thus suppressing this extra
+option or using
+.B PTRACE_SEIZE
+and thus suppressing this extra
 .B SIGTRAP
 is the recommended approach.
 .SS Real parent
@@ -1575,21 +1924,19 @@ exist; see BUGS below.
 .LP
 As of Linux 2.6.38, the following is believed to work correctly:
 .IP * 3
-exit/death by signal is reported first to the tracer, then, when the tracer
-consumes the
+exit/death by signal is reported first to the tracer, then,
+when the tracer consumes the
 .BR waitpid (2)
 result, to the real parent (to the real parent only when the
 whole multithreaded process exits).
-.\"
-.\" FIXME mtk: Please check: In the next line, 
-.\" I changed "they" to "the tracer and the real parent". Okay?
 If the tracer and the real parent are the same process,
 the report is sent only once.
-.SH "RETURN VALUE"
-On success,
+.SH RETURN VALUE
+On success, the
 .B PTRACE_PEEK*
-requests return the requested data,
+requests return the requested data (but see NOTES),
 while other requests return zero.
+.LP
 On error, all requests return \-1, and
 .I errno
 is set appropriately.
@@ -1633,19 +1980,16 @@ tracer has insufficient privileges (the required capability is
 unprivileged processes cannot trace processes that they
 cannot send signals to or those running
 set-user-ID/set-group-ID programs, for obvious reasons.
-.\" 
-.\" FIXME I reworked the mention of init here to note
-.\" when the behavior changed for tracing init(8). Okay?
 Alternatively, the process may already be being traced,
 or (on kernels before 2.6.26) be
-.BR init (8)
+.BR init (1)
 (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 a stopped tracee).
-.SH "CONFORMING TO"
+.SH CONFORMING TO
 SVr4, 4.3BSD.
 .SH NOTES
 Although arguments to
@@ -1656,18 +2000,21 @@ glibc currently declares
 as a variadic function with only the
 .I request
 argument fixed.
-This means that unneeded trailing arguments may be omitted,
-though doing so makes use of undocumented
-.BR gcc (1)
-behavior.
-.\" FIXME Please review. I reinstated the following, noting the
-.\" kernel version number where it ceased to be true
+It is recommended to always supply four arguments,
+even if the requested operation does not use them,
+setting unused/ignored arguments to
+.I 0L
+or
+.IR "(void\ *)\ 0".
 .LP
 In Linux kernels before 2.6.26,
 .\" See commit 00cd5c37afd5f431ac186dd131705048c0a11fdb
-.BR init (8),
+.BR init (1),
 the process with PID 1, may not be traced.
 .LP
+A tracees parent continues to be the tracer even if that tracer calls
+.BR execve (2).
+.LP
 The layout of the contents of memory and the USER area are
 quite operating-system- and architecture-specific.
 The offset supplied, and the data returned,
@@ -1676,41 +2023,27 @@ might not entirely match with the definition of
 .\" See http://lkml.org/lkml/2008/5/8/375
 .LP
 The size of a "word" is determined by the operating-system variant
-(e.g., for 32-bit Linux it is 32 bits, etc.).
-.\" FIXME So, can we just remove the following text?
-.\"
-.\" Covered in more details above: (removed by dv)
-.\" .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 waitpid (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
+(e.g., for 32-bit Linux it is 32 bits).
+.LP
 This page documents the way the
 .BR ptrace ()
 call works currently in Linux.
-Its behavior differs noticeably on other flavors of UNIX.
+Its behavior differs significantly on other flavors of UNIX.
 In any case, use of
 .BR ptrace ()
 is highly specific to the operating system and architecture.
+.SS C library/kernel differences
+At the system call level, the
+.BR PTRACE_PEEKTEXT ,
+.BR PTRACE_PEEKDATA ,
+and
+.BR PTRACE_PEEKUSER
+requests have a different API: they store the result
+at the address specified by the
+.I data
+parameter, and the return value is the error flag.
+The glibc wrapper function provides the API given in DESCRIPTION above,
+with the result being returned via the function return value.
 .SH BUGS
 On hosts with 2.6 kernel headers,
 .B PTRACE_SETOPTIONS
@@ -1726,11 +2059,17 @@ if that is defined.
 Group-stop notifications are sent to the tracer, but not to real parent.
 Last confirmed on 2.6.38.6.
 .LP
-.\" 
-.\" FIXME Does "exits" in the following mean
-.\" just "_exit(2)" or or both "_exit(2) and exit_group(2)"?
 If a thread group leader is traced and exits by calling
 .BR _exit (2),
+.\" Note from Denys Vlasenko:
+.\"     Here "exits" means any kind of death - _exit, exit_group,
+.\"     signal death. Signal death and exit_group cases are trivial,
+.\"     though: since signal death and exit_group kill all other threads
+.\"     too, "until all other threads exit" thing happens rather soon
+.\"     in these cases. Therefore, only _exit presents observably
+.\"     puzzling behavior to ptrace users: thread leader _exit's,
+.\"     but WIFEXITED isn't reported! We are trying to explain here
+.\"     why it is so.
 a
 .B PTRACE_EVENT_EXIT
 stop will happen for it (if requested), but the subsequent
@@ -1749,9 +2088,7 @@ One possible workaround is to
 .B PTRACE_DETACH
 the thread group leader instead of restarting it in this case.
 Last confirmed on 2.6.38.6.
-.\"        ^^^ need to test/verify this scenario
-.\" FIXME: mtk: the preceding comment seems to be unresolved?
-.\"        Do you want to add anything?
+.\"  FIXME . need to test/verify this scenario
 .LP
 A
 .B SIGKILL
@@ -1761,14 +2098,76 @@ stop before actual signal death.
 This may be changed in the future;
 .B SIGKILL
 is meant to always immediately kill tasks even under ptrace.
-Last confirmed on 2.6.38.6.
-.SH "SEE ALSO"
+Last confirmed on Linux 3.13.
+.LP
+Some system calls return with
+.B EINTR
+if a signal was sent to a tracee, but delivery was suppressed by the tracer.
+(This is very typical operation: it is usually
+done by debuggers on every attach, in order to not introduce
+a bogus
+.BR SIGSTOP ).
+As of Linux 3.2.9, the following system calls are affected
+(this list is likely incomplete):
+.BR epoll_wait (2),
+and
+.BR read (2)
+from an
+.BR inotify (7)
+file descriptor.
+The usual symptom of this bug is that when you attach to
+a quiescent process with the command
+
+    strace \-p <process-ID>
+
+then, instead of the usual
+and expected one-line output such as
+.nf
+
+    restart_syscall(<... resuming interrupted call ...>_
+
+.fi
+or
+.nf
+
+    select(6, [5], NULL, [5], NULL_
+
+.fi
+('_' denotes the cursor position), you observe more than one line.
+For example:
+.nf
+
+    clock_gettime(CLOCK_MONOTONIC, {15370, 690928118}) = 0
+    epoll_wait(4,_
+
+.fi
+What is not visible here is that the process was blocked in
+.BR epoll_wait (2)
+before
+.BR strace (1)
+has attached to it.
+Attaching caused
+.BR epoll_wait (2)
+to return to user space with the error
+.BR EINTR .
+In this particular case, the program reacted to
+.B EINTR
+by checking the current time, and then executing
+.BR epoll_wait (2)
+again.
+(Programs which do not expect such "stray"
+.BR EINTR
+errors may behave in an unintended way upon an
+.BR strace (1)
+attach.)
+.SH SEE ALSO
 .BR gdb (1),
 .BR strace (1),
 .BR clone (2),
 .BR execve (2),
 .BR fork (2),
 .BR gettid (2),
+.BR seccomp (2),
 .BR sigaction (2),
 .BR tgkill (2),
 .BR vfork (2),