Blame man2/ptrace.2

Packit 7cfc04
.\" Copyright (c) 1993 Michael Haardt <michael@moria.de>
Packit 7cfc04
.\" Fri Apr  2 11:32:09 MET DST 1993
Packit 7cfc04
.\"
Packit 7cfc04
.\" and changes Copyright (C) 1999 Mike Coleman (mkc@acm.org)
Packit 7cfc04
.\" -- major revision to fully document ptrace semantics per recent Linux
Packit 7cfc04
.\"    kernel (2.2.10) and glibc (2.1.2)
Packit 7cfc04
.\" Sun Nov  7 03:18:35 CST 1999
Packit 7cfc04
.\"
Packit 7cfc04
.\" and Copyright (c) 2011, Denys Vlasenko <vda.linux@googlemail.com>
Packit 7cfc04
.\" and Copyright (c) 2015, 2016, Michael Kerrisk <mtk.manpages@gmail.com>
Packit 7cfc04
.\"
Packit 7cfc04
.\" %%%LICENSE_START(GPLv2+_DOC_FULL)
Packit 7cfc04
.\" This is free documentation; you can redistribute it and/or
Packit 7cfc04
.\" modify it under the terms of the GNU General Public License as
Packit 7cfc04
.\" published by the Free Software Foundation; either version 2 of
Packit 7cfc04
.\" the License, or (at your option) any later version.
Packit 7cfc04
.\"
Packit 7cfc04
.\" The GNU General Public License's references to "object code"
Packit 7cfc04
.\" and "executables" are to be interpreted as the output of any
Packit 7cfc04
.\" document formatting or typesetting system, including
Packit 7cfc04
.\" intermediate and printed output.
Packit 7cfc04
.\"
Packit 7cfc04
.\" This manual is distributed in the hope that it will be useful,
Packit 7cfc04
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 7cfc04
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 7cfc04
.\" GNU General Public License for more details.
Packit 7cfc04
.\"
Packit 7cfc04
.\" You should have received a copy of the GNU General Public
Packit 7cfc04
.\" License along with this manual; if not, see
Packit 7cfc04
.\" <http://www.gnu.org/licenses/>.
Packit 7cfc04
.\" %%%LICENSE_END
Packit 7cfc04
.\"
Packit 7cfc04
.\" Modified Fri Jul 23 23:47:18 1993 by Rik Faith <faith@cs.unc.edu>
Packit 7cfc04
.\" Modified Fri Jan 31 16:46:30 1997 by Eric S. Raymond <esr@thyrsus.com>
Packit 7cfc04
.\" Modified Thu Oct  7 17:28:49 1999 by Andries Brouwer <aeb@cwi.nl>
Packit 7cfc04
.\" Modified, 27 May 2004, Michael Kerrisk <mtk.manpages@gmail.com>
Packit 7cfc04
.\"     Added notes on capability requirements
Packit 7cfc04
.\"
Packit 7cfc04
.\" 2006-03-24, Chuck Ebbert <76306.1226@compuserve.com>
Packit 7cfc04
.\"    Added    PTRACE_SETOPTIONS, PTRACE_GETEVENTMSG, PTRACE_GETSIGINFO,
Packit 7cfc04
.\"        PTRACE_SETSIGINFO, PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP
Packit 7cfc04
.\"    (Thanks to Blaisorblade, Daniel Jacobowitz and others who helped.)
Packit 7cfc04
.\" 2011-09, major update by Denys Vlasenko <vda.linux@googlemail.com>
Packit 7cfc04
.\" 2015-01, Kees Cook <keescook@chromium.org>
Packit 7cfc04
.\"    Added PTRACE_O_TRACESECCOMP, PTRACE_EVENT_SECCOMP
Packit 7cfc04
.\"
Packit 7cfc04
.\" FIXME The following are undocumented:
Packit 7cfc04
.\"
Packit 7cfc04
.\" PTRACE_GETWMMXREGS
Packit 7cfc04
.\" PTRACE_SETWMMXREGS
Packit 7cfc04
.\"	ARM
Packit 7cfc04
.\" 	Linux 2.6.12
Packit 7cfc04
.\"
Packit 7cfc04
.\" PTRACE_SET_SYSCALL
Packit 7cfc04
.\"	ARM and ARM64
Packit 7cfc04
.\"	Linux 2.6.16
Packit 7cfc04
.\"	commit 3f471126ee53feb5e9b210ea2f525ed3bb9b7a7f
Packit 7cfc04
.\"	Author: Nicolas Pitre <nico@cam.org>
Packit 7cfc04
.\"	Date:   Sat Jan 14 19:30:04 2006 +0000
Packit 7cfc04
.\"
Packit 7cfc04
.\" PTRACE_GETCRUNCHREGS
Packit 7cfc04
.\" PTRACE_SETCRUNCHREGS
Packit 7cfc04
.\"	ARM
Packit 7cfc04
.\"	Linux 2.6.18
Packit 7cfc04
.\"	commit 3bec6ded282b331552587267d67a06ed7fd95ddd
Packit 7cfc04
.\"	Author: Lennert Buytenhek <buytenh@wantstofly.org>
Packit 7cfc04
.\"	Date:   Tue Jun 27 22:56:18 2006 +0100
Packit 7cfc04
.\"
Packit 7cfc04
.\" PTRACE_GETVFPREGS
Packit 7cfc04
.\" PTRACE_SETVFPREGS
Packit 7cfc04
.\"	ARM and ARM64
Packit 7cfc04
.\"	Linux 2.6.30
Packit 7cfc04
.\"	commit 3d1228ead618b88e8606015cbabc49019981805d
Packit 7cfc04
.\"	Author: Catalin Marinas <catalin.marinas@arm.com>
Packit 7cfc04
.\"	Date:   Wed Feb 11 13:12:56 2009 +0100
Packit 7cfc04
.\"
Packit 7cfc04
.\" PTRACE_GETHBPREGS
Packit 7cfc04
.\" PTRACE_SETHBPREGS
Packit 7cfc04
.\"	ARM and ARM64
Packit 7cfc04
.\"	Linux 2.6.37
Packit 7cfc04
.\"	commit 864232fa1a2f8dfe003438ef0851a56722740f3e
Packit 7cfc04
.\"	Author: Will Deacon <will.deacon@arm.com>
Packit 7cfc04
.\"	Date:   Fri Sep 3 10:42:55 2010 +0100
Packit 7cfc04
.\"
Packit 7cfc04
.\" PTRACE_SINGLEBLOCK
Packit 7cfc04
.\"	Since at least Linux 2.4.0 on various architectures
Packit 7cfc04
.\"	Since Linux 2.6.25 on x86 (and others?)
Packit 7cfc04
.\"	commit 5b88abbf770a0e1975c668743100f42934f385e8
Packit 7cfc04
.\"	Author: Roland McGrath <roland@redhat.com>
Packit 7cfc04
.\"	Date:   Wed Jan 30 13:30:53 2008 +0100
Packit 7cfc04
.\"	    ptrace: generic PTRACE_SINGLEBLOCK
Packit 7cfc04
.\"
Packit 7cfc04
.\" PTRACE_GETFPXREGS
Packit 7cfc04
.\" PTRACE_SETFPXREGS
Packit 7cfc04
.\"	Since at least Linux 2.4.0 on various architectures
Packit 7cfc04
.\"
Packit 7cfc04
.\" PTRACE_GETFDPIC
Packit 7cfc04
.\" PTRACE_GETFDPIC_EXEC
Packit 7cfc04
.\" PTRACE_GETFDPIC_INTERP
Packit 7cfc04
.\"	blackfin, c6x, frv, sh
Packit 7cfc04
.\"	First appearance in Linux 2.6.11 on frv
Packit 7cfc04
.\"
Packit 7cfc04
.\" and others that can be found in the arch/*/include/uapi/asm/ptrace files
Packit 7cfc04
.\"
Packit 7cfc04
.TH PTRACE 2 2017-09-15 "Linux" "Linux Programmer's Manual"
Packit 7cfc04
.SH NAME
Packit 7cfc04
ptrace \- process trace
Packit 7cfc04
.SH SYNOPSIS
Packit 7cfc04
.nf
Packit 7cfc04
.B #include <sys/ptrace.h>
Packit 7cfc04
.PP
Packit 7cfc04
.BI "long ptrace(enum __ptrace_request " request ", pid_t " pid ", "
Packit 7cfc04
.BI "            void *" addr ", void *" data );
Packit 7cfc04
.fi
Packit 7cfc04
.SH DESCRIPTION
Packit 7cfc04
The
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
system call provides a means by which one process (the "tracer")
Packit 7cfc04
may observe and control the execution of another process (the "tracee"),
Packit 7cfc04
and examine and change the tracee's memory and registers.
Packit 7cfc04
It is primarily used to implement breakpoint debugging and system
Packit 7cfc04
call tracing.
Packit 7cfc04
.PP
Packit 7cfc04
A tracee first needs to be attached to the tracer.
Packit 7cfc04
Attachment and subsequent commands are per thread:
Packit 7cfc04
in a multithreaded process,
Packit 7cfc04
every thread can be individually attached to a
Packit 7cfc04
(potentially different) tracer,
Packit 7cfc04
or left not attached and thus not debugged.
Packit 7cfc04
Therefore, "tracee" always means "(one) thread",
Packit 7cfc04
never "a (possibly multithreaded) process".
Packit 7cfc04
Ptrace commands are always sent to
Packit 7cfc04
a specific tracee using a call of the form
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_foo, pid, ...)
Packit 7cfc04
.PP
Packit 7cfc04
where
Packit 7cfc04
.I pid
Packit 7cfc04
is the thread ID of the corresponding Linux thread.
Packit 7cfc04
.PP
Packit 7cfc04
(Note that in this page, a "multithreaded process"
Packit 7cfc04
means a thread group consisting of threads created using the
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
.B CLONE_THREAD
Packit 7cfc04
flag.)
Packit 7cfc04
.PP
Packit 7cfc04
A process can initiate a trace by calling
Packit 7cfc04
.BR fork (2)
Packit 7cfc04
and having the resulting child do a
Packit 7cfc04
.BR PTRACE_TRACEME ,
Packit 7cfc04
followed (typically) by an
Packit 7cfc04
.BR execve (2).
Packit 7cfc04
Alternatively, one process may commence tracing another process using
Packit 7cfc04
.B PTRACE_ATTACH
Packit 7cfc04
or
Packit 7cfc04
.BR PTRACE_SEIZE .
Packit 7cfc04
.PP
Packit 7cfc04
While being traced, the tracee will stop each time a signal is delivered,
Packit 7cfc04
even if the signal is being ignored.
Packit 7cfc04
(An exception is
Packit 7cfc04
.BR SIGKILL ,
Packit 7cfc04
which has its usual effect.)
Packit 7cfc04
The tracer will be notified at its next call to
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
(or one of the related "wait" system calls); that call will return a
Packit 7cfc04
.I status
Packit 7cfc04
value containing information that indicates
Packit 7cfc04
the cause of the stop in the tracee.
Packit 7cfc04
While the tracee is stopped,
Packit 7cfc04
the tracer can use various ptrace requests to inspect and modify the tracee.
Packit 7cfc04
The tracer then causes the tracee to continue,
Packit 7cfc04
optionally ignoring the delivered signal
Packit 7cfc04
(or even delivering a different signal instead).
Packit 7cfc04
.PP
Packit 7cfc04
If the
Packit 7cfc04
.B PTRACE_O_TRACEEXEC
Packit 7cfc04
option is not in effect, all successful calls to
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
by the traced process will cause it to be sent a
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
signal,
Packit 7cfc04
giving the parent a chance to gain control before the new program
Packit 7cfc04
begins execution.
Packit 7cfc04
.PP
Packit 7cfc04
When the tracer is finished tracing, it can cause the tracee to continue
Packit 7cfc04
executing in a normal, untraced mode via
Packit 7cfc04
.BR PTRACE_DETACH .
Packit 7cfc04
.PP
Packit 7cfc04
The value of
Packit 7cfc04
.I request
Packit 7cfc04
determines the action to be performed:
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_TRACEME
Packit 7cfc04
Indicate that this process is to be traced by its parent.
Packit 7cfc04
A process probably shouldn't make this request if its parent
Packit 7cfc04
isn't expecting to trace it.
Packit 7cfc04
.RI ( pid ,
Packit 7cfc04
.IR addr ,
Packit 7cfc04
and
Packit 7cfc04
.IR data
Packit 7cfc04
are ignored.)
Packit 7cfc04
.IP
Packit 7cfc04
The
Packit 7cfc04
.B PTRACE_TRACEME
Packit 7cfc04
request is used only by the tracee;
Packit 7cfc04
the remaining requests are used only by the tracer.
Packit 7cfc04
In the following requests,
Packit 7cfc04
.I pid
Packit 7cfc04
specifies the thread ID of the tracee to be acted on.
Packit 7cfc04
For requests other than
Packit 7cfc04
.BR PTRACE_ATTACH ,
Packit 7cfc04
.BR PTRACE_SEIZE ,
Packit 7cfc04
.BR PTRACE_INTERRUPT ,
Packit 7cfc04
and
Packit 7cfc04
.BR PTRACE_KILL ,
Packit 7cfc04
the tracee must be stopped.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_PEEKTEXT ", " PTRACE_PEEKDATA
Packit 7cfc04
Read a word at the address
Packit 7cfc04
.I addr
Packit 7cfc04
in the tracee's memory, returning the word as the result of the
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
call.
Packit 7cfc04
Linux does not have separate text and data address spaces,
Packit 7cfc04
so these two requests are currently equivalent.
Packit 7cfc04
.RI ( data
Packit 7cfc04
is ignored; but see NOTES.)
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_PEEKUSER
Packit 7cfc04
.\" PTRACE_PEEKUSR in kernel source, but glibc uses PTRACE_PEEKUSER,
Packit 7cfc04
.\" and that is the name that seems common on other systems.
Packit 7cfc04
Read a word at offset
Packit 7cfc04
.I addr
Packit 7cfc04
in the tracee's USER area,
Packit 7cfc04
which holds the registers and other information about the process
Packit 7cfc04
(see
Packit 7cfc04
.IR <sys/user.h> ).
Packit 7cfc04
The word is returned as the result of the
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
call.
Packit 7cfc04
Typically, the offset must be word-aligned, though this might vary by
Packit 7cfc04
architecture.
Packit 7cfc04
See NOTES.
Packit 7cfc04
.RI ( data
Packit 7cfc04
is ignored; but see NOTES.)
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_POKETEXT ", " PTRACE_POKEDATA
Packit 7cfc04
Copy the word
Packit 7cfc04
.I data
Packit 7cfc04
to the address
Packit 7cfc04
.I addr
Packit 7cfc04
in the tracee's memory.
Packit 7cfc04
As for
Packit 7cfc04
.BR PTRACE_PEEKTEXT
Packit 7cfc04
and
Packit 7cfc04
.BR PTRACE_PEEKDATA ,
Packit 7cfc04
these two requests are currently equivalent.
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_POKEUSER
Packit 7cfc04
.\" PTRACE_POKEUSR in kernel source, but glibc uses PTRACE_POKEUSER,
Packit 7cfc04
.\" and that is the name that seems common on other systems.
Packit 7cfc04
Copy the word
Packit 7cfc04
.I data
Packit 7cfc04
to offset
Packit 7cfc04
.I addr
Packit 7cfc04
in the tracee's USER area.
Packit 7cfc04
As for
Packit 7cfc04
.BR PTRACE_PEEKUSER ,
Packit 7cfc04
the offset must typically be word-aligned.
Packit 7cfc04
In order to maintain the integrity of the kernel,
Packit 7cfc04
some modifications to the USER area are disallowed.
Packit 7cfc04
.\" FIXME In the preceding sentence, which modifications are disallowed,
Packit 7cfc04
.\" and when they are disallowed, how does user space discover that fact?
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_GETREGS ", " PTRACE_GETFPREGS
Packit 7cfc04
Copy the tracee's general-purpose or floating-point registers,
Packit 7cfc04
respectively, to the address
Packit 7cfc04
.I data
Packit 7cfc04
in the tracer.
Packit 7cfc04
See
Packit 7cfc04
.I <sys/user.h>
Packit 7cfc04
for information on the format of this data.
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
Note that SPARC systems have the meaning of
Packit 7cfc04
.I data
Packit 7cfc04
and
Packit 7cfc04
.I addr
Packit 7cfc04
reversed; that is,
Packit 7cfc04
.I data
Packit 7cfc04
is ignored and the registers are copied to the address
Packit 7cfc04
.IR addr .
Packit 7cfc04
.B PTRACE_GETREGS
Packit 7cfc04
and
Packit 7cfc04
.B PTRACE_GETFPREGS
Packit 7cfc04
are not present on all architectures.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_GETREGSET " (since Linux 2.6.34)"
Packit 7cfc04
Read the tracee's registers.
Packit 7cfc04
.I addr
Packit 7cfc04
specifies, in an architecture-dependent way, the type of registers to be read.
Packit 7cfc04
.B NT_PRSTATUS
Packit 7cfc04
(with numerical value 1)
Packit 7cfc04
usually results in reading of general-purpose registers.
Packit 7cfc04
If the CPU has, for example,
Packit 7cfc04
floating-point and/or vector registers, they can be retrieved by setting
Packit 7cfc04
.I addr
Packit 7cfc04
to the corresponding
Packit 7cfc04
.B NT_foo
Packit 7cfc04
constant.
Packit 7cfc04
.I data
Packit 7cfc04
points to a
Packit 7cfc04
.BR "struct iovec" ,
Packit 7cfc04
which describes the destination buffer's location and length.
Packit 7cfc04
On return, the kernel modifies
Packit 7cfc04
.B iov.len
Packit 7cfc04
to indicate the actual number of bytes returned.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SETREGS ", " PTRACE_SETFPREGS
Packit 7cfc04
Modify the tracee's general-purpose or floating-point registers,
Packit 7cfc04
respectively, from the address
Packit 7cfc04
.I data
Packit 7cfc04
in the tracer.
Packit 7cfc04
As for
Packit 7cfc04
.BR PTRACE_POKEUSER ,
Packit 7cfc04
some general-purpose register modifications may be disallowed.
Packit 7cfc04
.\" FIXME . In the preceding sentence, which modifications are disallowed,
Packit 7cfc04
.\" and when they are disallowed, how does user space discover that fact?
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
Note that SPARC systems have the meaning of
Packit 7cfc04
.I data
Packit 7cfc04
and
Packit 7cfc04
.I addr
Packit 7cfc04
reversed; that is,
Packit 7cfc04
.I data
Packit 7cfc04
is ignored and the registers are copied from the address
Packit 7cfc04
.IR addr .
Packit 7cfc04
.B PTRACE_SETREGS
Packit 7cfc04
and
Packit 7cfc04
.B PTRACE_SETFPREGS
Packit 7cfc04
are not present on all architectures.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SETREGSET " (since Linux 2.6.34)"
Packit 7cfc04
Modify the tracee's registers.
Packit 7cfc04
The meaning of
Packit 7cfc04
.I addr
Packit 7cfc04
and
Packit 7cfc04
.I data
Packit 7cfc04
is analogous to
Packit 7cfc04
.BR PTRACE_GETREGSET .
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_GETSIGINFO " (since Linux 2.3.99-pre6)"
Packit 7cfc04
Retrieve information about the signal that caused the stop.
Packit 7cfc04
Copy a
Packit 7cfc04
.I siginfo_t
Packit 7cfc04
structure (see
Packit 7cfc04
.BR sigaction (2))
Packit 7cfc04
from the tracee to the address
Packit 7cfc04
.I data
Packit 7cfc04
in the tracer.
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SETSIGINFO " (since Linux 2.3.99-pre6)"
Packit 7cfc04
Set signal information:
Packit 7cfc04
copy a
Packit 7cfc04
.I siginfo_t
Packit 7cfc04
structure from the address
Packit 7cfc04
.I data
Packit 7cfc04
in the tracer to the tracee.
Packit 7cfc04
This will affect only signals that would normally be delivered to
Packit 7cfc04
the tracee and were caught by the tracer.
Packit 7cfc04
It may be difficult to tell
Packit 7cfc04
these normal signals from synthetic signals generated by
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
itself.
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_PEEKSIGINFO " (since Linux 3.10)"
Packit 7cfc04
.\" commit 84c751bd4aebbaae995fe32279d3dba48327bad4
Packit 7cfc04
Retrieve
Packit 7cfc04
.I siginfo_t
Packit 7cfc04
structures without removing signals from a queue.
Packit 7cfc04
.I addr
Packit 7cfc04
points to a
Packit 7cfc04
.I ptrace_peeksiginfo_args
Packit 7cfc04
structure that specifies the ordinal position from which
Packit 7cfc04
copying of signals should start,
Packit 7cfc04
and the number of signals to copy.
Packit 7cfc04
.I siginfo_t
Packit 7cfc04
structures are copied into the buffer pointed to by
Packit 7cfc04
.IR data .
Packit 7cfc04
The return value contains the number of copied signals (zero indicates
Packit 7cfc04
that there is no signal corresponding to the specified ordinal position).
Packit 7cfc04
Within the returned
Packit 7cfc04
.I siginfo
Packit 7cfc04
structures,
Packit 7cfc04
the
Packit 7cfc04
.IR si_code
Packit 7cfc04
field includes information
Packit 7cfc04
.RB ( __SI_CHLD ,
Packit 7cfc04
.BR __SI_FAULT ,
Packit 7cfc04
etc.) that are not otherwise exposed to user space.
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
struct ptrace_peeksiginfo_args {
Packit 7cfc04
    u64 off;    /* Ordinal position in queue at which
Packit 7cfc04
                   to start copying signals */
Packit 7cfc04
    u32 flags;  /* PTRACE_PEEKSIGINFO_SHARED or 0 */
Packit 7cfc04
    s32 nr;     /* Number of signals to copy */
Packit 7cfc04
};
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.IP
Packit 7cfc04
Currently, there is only one flag,
Packit 7cfc04
.BR PTRACE_PEEKSIGINFO_SHARED ,
Packit 7cfc04
for dumping signals from the process-wide signal queue.
Packit 7cfc04
If this flag is not set,
Packit 7cfc04
signals are read from the per-thread queue of the specified thread.
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_GETSIGMASK " (since Linux 3.11)"
Packit 7cfc04
.\" commit 29000caecbe87b6b66f144f72111f0d02fbbf0c1
Packit 7cfc04
Place a copy of the mask of blocked signals (see
Packit 7cfc04
.BR sigprocmask (2))
Packit 7cfc04
in the buffer pointed to by
Packit 7cfc04
.IR data ,
Packit 7cfc04
which should be a pointer to a buffer of type
Packit 7cfc04
.IR sigset_t .
Packit 7cfc04
The
Packit 7cfc04
.I addr
Packit 7cfc04
argument contains the size of the buffer pointed to by
Packit 7cfc04
.IR data
Packit 7cfc04
(i.e.,
Packit 7cfc04
.IR sizeof(sigset_t) ).
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SETSIGMASK " (since Linux 3.11)"
Packit 7cfc04
Change the mask of blocked signals (see
Packit 7cfc04
.BR sigprocmask (2))
Packit 7cfc04
to the value specified in the buffer pointed to by
Packit 7cfc04
.IR data ,
Packit 7cfc04
which should be a pointer to a buffer of type
Packit 7cfc04
.IR sigset_t .
Packit 7cfc04
The
Packit 7cfc04
.I addr
Packit 7cfc04
argument contains the size of the buffer pointed to by
Packit 7cfc04
.IR data
Packit 7cfc04
(i.e.,
Packit 7cfc04
.IR sizeof(sigset_t) ).
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SETOPTIONS " (since Linux 2.4.6; see BUGS for caveats)"
Packit 7cfc04
Set ptrace options from
Packit 7cfc04
.IR data .
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
.IR data
Packit 7cfc04
is interpreted as a bit mask of options,
Packit 7cfc04
which are specified by the following flags:
Packit 7cfc04
.RS
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_EXITKILL " (since Linux 3.8)"
Packit 7cfc04
.\" commit 992fb6e170639b0849bace8e49bf31bd37c4123
Packit 7cfc04
Send a
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
signal to the tracee if the tracer exits.
Packit 7cfc04
This option is useful for ptrace jailers that
Packit 7cfc04
want to ensure that tracees can never escape the tracer's control.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_TRACECLONE " (since Linux 2.5.46)"
Packit 7cfc04
Stop the tracee at the next
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
and automatically start tracing the newly cloned process,
Packit 7cfc04
which will start with a
Packit 7cfc04
.BR SIGSTOP ,
Packit 7cfc04
or
Packit 7cfc04
.B PTRACE_EVENT_STOP
Packit 7cfc04
if
Packit 7cfc04
.B PTRACE_SEIZE
Packit 7cfc04
was used.
Packit 7cfc04
A
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
by the tracer will return a
Packit 7cfc04
.I status
Packit 7cfc04
value such that
Packit 7cfc04
.IP
Packit 7cfc04
.nf
Packit 7cfc04
  status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8))
Packit 7cfc04
.fi
Packit 7cfc04
.IP
Packit 7cfc04
The PID of the new process can be retrieved with
Packit 7cfc04
.BR PTRACE_GETEVENTMSG .
Packit 7cfc04
.IP
Packit 7cfc04
This option may not catch
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
calls in all cases.
Packit 7cfc04
If the tracee calls
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
with the
Packit 7cfc04
.B CLONE_VFORK
Packit 7cfc04
flag,
Packit 7cfc04
.B PTRACE_EVENT_VFORK
Packit 7cfc04
will be delivered instead
Packit 7cfc04
if
Packit 7cfc04
.B PTRACE_O_TRACEVFORK
Packit 7cfc04
is set; otherwise if the tracee calls
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
with the exit signal set to
Packit 7cfc04
.BR SIGCHLD ,
Packit 7cfc04
.B PTRACE_EVENT_FORK
Packit 7cfc04
will be delivered if
Packit 7cfc04
.B PTRACE_O_TRACEFORK
Packit 7cfc04
is set.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_TRACEEXEC " (since Linux 2.5.46)"
Packit 7cfc04
Stop the tracee at the next
Packit 7cfc04
.BR execve (2).
Packit 7cfc04
A
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
by the tracer will return a
Packit 7cfc04
.I status
Packit 7cfc04
value such that
Packit 7cfc04
.IP
Packit 7cfc04
.nf
Packit 7cfc04
  status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))
Packit 7cfc04
.fi
Packit 7cfc04
.IP
Packit 7cfc04
If the execing thread is not a thread group leader,
Packit 7cfc04
the thread ID is reset to thread group leader's ID before this stop.
Packit 7cfc04
Since Linux 3.0, the former thread ID can be retrieved with
Packit 7cfc04
.BR PTRACE_GETEVENTMSG .
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_TRACEEXIT " (since Linux 2.5.60)"
Packit 7cfc04
Stop the tracee at exit.
Packit 7cfc04
A
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
by the tracer will return a
Packit 7cfc04
.I status
Packit 7cfc04
value such that
Packit 7cfc04
.IP
Packit 7cfc04
.nf
Packit 7cfc04
  status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))
Packit 7cfc04
.fi
Packit 7cfc04
.IP
Packit 7cfc04
The tracee's exit status can be retrieved with
Packit 7cfc04
.BR PTRACE_GETEVENTMSG .
Packit 7cfc04
.IP
Packit 7cfc04
The tracee is stopped early during process exit,
Packit 7cfc04
when registers are still available,
Packit 7cfc04
allowing the tracer to see where the exit occurred,
Packit 7cfc04
whereas the normal exit notification is done after the process
Packit 7cfc04
is finished exiting.
Packit 7cfc04
Even though context is available,
Packit 7cfc04
the tracer cannot prevent the exit from happening at this point.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_TRACEFORK " (since Linux 2.5.46)"
Packit 7cfc04
Stop the tracee at the next
Packit 7cfc04
.BR fork (2)
Packit 7cfc04
and automatically start tracing the newly forked process,
Packit 7cfc04
which will start with a
Packit 7cfc04
.BR SIGSTOP ,
Packit 7cfc04
or
Packit 7cfc04
.B PTRACE_EVENT_STOP
Packit 7cfc04
if
Packit 7cfc04
.B PTRACE_SEIZE
Packit 7cfc04
was used.
Packit 7cfc04
A
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
by the tracer will return a
Packit 7cfc04
.I status
Packit 7cfc04
value such that
Packit 7cfc04
.IP
Packit 7cfc04
.nf
Packit 7cfc04
  status>>8 == (SIGTRAP | (PTRACE_EVENT_FORK<<8))
Packit 7cfc04
.fi
Packit 7cfc04
.IP
Packit 7cfc04
The PID of the new process can be retrieved with
Packit 7cfc04
.BR PTRACE_GETEVENTMSG .
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_TRACESYSGOOD " (since Linux 2.4.6)"
Packit 7cfc04
When delivering system call traps, set bit 7 in the signal number
Packit 7cfc04
(i.e., deliver
Packit 7cfc04
.IR "SIGTRAP|0x80" ).
Packit 7cfc04
This makes it easy for the tracer to distinguish
Packit 7cfc04
normal traps from those caused by a system call.
Packit 7cfc04
.RB ( PTRACE_O_TRACESYSGOOD
Packit 7cfc04
may not work on all architectures.)
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_TRACEVFORK " (since Linux 2.5.46)"
Packit 7cfc04
Stop the tracee at the next
Packit 7cfc04
.BR vfork (2)
Packit 7cfc04
and automatically start tracing the newly vforked process,
Packit 7cfc04
which will start with a
Packit 7cfc04
.BR SIGSTOP ,
Packit 7cfc04
or
Packit 7cfc04
.B PTRACE_EVENT_STOP
Packit 7cfc04
if
Packit 7cfc04
.B PTRACE_SEIZE
Packit 7cfc04
was used.
Packit 7cfc04
A
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
by the tracer will return a
Packit 7cfc04
.I status
Packit 7cfc04
value such that
Packit 7cfc04
.IP
Packit 7cfc04
.nf
Packit 7cfc04
  status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK<<8))
Packit 7cfc04
.fi
Packit 7cfc04
.IP
Packit 7cfc04
The PID of the new process can be retrieved with
Packit 7cfc04
.BR PTRACE_GETEVENTMSG .
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_TRACEVFORKDONE " (since Linux 2.5.60)"
Packit 7cfc04
Stop the tracee at the completion of the next
Packit 7cfc04
.BR vfork (2).
Packit 7cfc04
A
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
by the tracer will return a
Packit 7cfc04
.I status
Packit 7cfc04
value such that
Packit 7cfc04
.IP
Packit 7cfc04
.nf
Packit 7cfc04
  status>>8 == (SIGTRAP | (PTRACE_EVENT_VFORK_DONE<<8))
Packit 7cfc04
.fi
Packit 7cfc04
.IP
Packit 7cfc04
The PID of the new process can (since Linux 2.6.18) be retrieved with
Packit 7cfc04
.BR PTRACE_GETEVENTMSG .
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_TRACESECCOMP " (since Linux 3.5)"
Packit 7cfc04
Stop the tracee when a
Packit 7cfc04
.BR seccomp (2)
Packit 7cfc04
.BR SECCOMP_RET_TRACE
Packit 7cfc04
rule is triggered.
Packit 7cfc04
A
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
by the tracer will return a
Packit 7cfc04
.I status
Packit 7cfc04
value such that
Packit 7cfc04
.IP
Packit 7cfc04
.nf
Packit 7cfc04
  status>>8 == (SIGTRAP | (PTRACE_EVENT_SECCOMP<<8))
Packit 7cfc04
.fi
Packit 7cfc04
.IP
Packit 7cfc04
While this triggers a
Packit 7cfc04
.BR PTRACE_EVENT
Packit 7cfc04
stop, it is similar to a syscall-enter-stop.
Packit 7cfc04
For details, see the note on
Packit 7cfc04
.B PTRACE_EVENT_SECCOMP
Packit 7cfc04
below.
Packit 7cfc04
The seccomp event message data (from the
Packit 7cfc04
.BR SECCOMP_RET_DATA
Packit 7cfc04
portion of the seccomp filter rule) can be retrieved with
Packit 7cfc04
.BR PTRACE_GETEVENTMSG .
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_O_SUSPEND_SECCOMP " (since Linux 4.3)"
Packit 7cfc04
.\" commit 13c4a90119d28cfcb6b5bdd820c233b86c2b0237
Packit 7cfc04
Suspend the tracee's seccomp protections.
Packit 7cfc04
This applies regardless of mode, and
Packit 7cfc04
can be used when the tracee has not yet installed seccomp filters.
Packit 7cfc04
That is, a valid use case is to suspend a tracee's seccomp protections
Packit 7cfc04
before they are installed by the tracee,
Packit 7cfc04
let the tracee install the filters,
Packit 7cfc04
and then clear this flag when the filters should be resumed.
Packit 7cfc04
Setting this option requires that the tracer have the
Packit 7cfc04
.BR CAP_SYS_ADMIN
Packit 7cfc04
capability,
Packit 7cfc04
not have any seccomp protections installed, and not have
Packit 7cfc04
.BR PTRACE_O_SUSPEND_SECCOMP
Packit 7cfc04
set on itself.
Packit 7cfc04
.RE
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_GETEVENTMSG " (since Linux 2.5.46)"
Packit 7cfc04
Retrieve a message (as an
Packit 7cfc04
.IR "unsigned long" )
Packit 7cfc04
about the ptrace event
Packit 7cfc04
that just happened, placing it at the address
Packit 7cfc04
.I data
Packit 7cfc04
in the tracer.
Packit 7cfc04
For
Packit 7cfc04
.BR PTRACE_EVENT_EXIT ,
Packit 7cfc04
this is the tracee's exit status.
Packit 7cfc04
For
Packit 7cfc04
.BR PTRACE_EVENT_FORK ,
Packit 7cfc04
.BR PTRACE_EVENT_VFORK ,
Packit 7cfc04
.BR PTRACE_EVENT_VFORK_DONE ,
Packit 7cfc04
and
Packit 7cfc04
.BR PTRACE_EVENT_CLONE ,
Packit 7cfc04
this is the PID of the new process.
Packit 7cfc04
For
Packit 7cfc04
.BR PTRACE_EVENT_SECCOMP ,
Packit 7cfc04
this is the
Packit 7cfc04
.BR seccomp (2)
Packit 7cfc04
filter's
Packit 7cfc04
.BR SECCOMP_RET_DATA
Packit 7cfc04
associated with the triggered rule.
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_CONT
Packit 7cfc04
Restart the stopped tracee process.
Packit 7cfc04
If
Packit 7cfc04
.I data
Packit 7cfc04
is nonzero,
Packit 7cfc04
it is interpreted as the number of a signal to be delivered to the tracee;
Packit 7cfc04
otherwise, no signal is delivered.
Packit 7cfc04
Thus, for example, the tracer can control
Packit 7cfc04
whether a signal sent to the tracee is delivered or not.
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SYSCALL ", " PTRACE_SINGLESTEP
Packit 7cfc04
Restart the stopped tracee as for
Packit 7cfc04
.BR PTRACE_CONT ,
Packit 7cfc04
but arrange for the tracee to be stopped at
Packit 7cfc04
the next entry to or exit from a system call,
Packit 7cfc04
or after execution of a single instruction, respectively.
Packit 7cfc04
(The tracee will also, as usual, be stopped upon receipt of a signal.)
Packit 7cfc04
From the tracer's perspective, the tracee will appear to have been
Packit 7cfc04
stopped by receipt of a
Packit 7cfc04
.BR SIGTRAP .
Packit 7cfc04
So, for
Packit 7cfc04
.BR PTRACE_SYSCALL ,
Packit 7cfc04
for example, the idea is to inspect
Packit 7cfc04
the arguments to the system call at the first stop,
Packit 7cfc04
then do another
Packit 7cfc04
.B PTRACE_SYSCALL
Packit 7cfc04
and inspect the return value of the system call at the second stop.
Packit 7cfc04
The
Packit 7cfc04
.I data
Packit 7cfc04
argument is treated as for
Packit 7cfc04
.BR PTRACE_CONT .
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SYSEMU ", " PTRACE_SYSEMU_SINGLESTEP " (since Linux 2.6.14)"
Packit 7cfc04
For
Packit 7cfc04
.BR PTRACE_SYSEMU ,
Packit 7cfc04
continue and stop on entry to the next system call,
Packit 7cfc04
which will not be executed.
Packit 7cfc04
See the documentation on syscall-stops below.
Packit 7cfc04
For
Packit 7cfc04
.BR PTRACE_SYSEMU_SINGLESTEP ,
Packit 7cfc04
do the same but also singlestep if not a system call.
Packit 7cfc04
This call is used by programs like
Packit 7cfc04
User Mode Linux that want to emulate all the tracee's system calls.
Packit 7cfc04
The
Packit 7cfc04
.I data
Packit 7cfc04
argument is treated as for
Packit 7cfc04
.BR PTRACE_CONT .
Packit 7cfc04
The
Packit 7cfc04
.I addr
Packit 7cfc04
argument is ignored.
Packit 7cfc04
These requests are currently
Packit 7cfc04
.\" As at 3.7
Packit 7cfc04
supported only on x86.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_LISTEN " (since Linux 3.4)"
Packit 7cfc04
Restart the stopped tracee, but prevent it from executing.
Packit 7cfc04
The resulting state of the tracee is similar to a process which
Packit 7cfc04
has been stopped by a
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
(or other stopping signal).
Packit 7cfc04
See the "group-stop" subsection for additional information.
Packit 7cfc04
.B PTRACE_LISTEN
Packit 7cfc04
works only on tracees attached by
Packit 7cfc04
.BR PTRACE_SEIZE .
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_KILL
Packit 7cfc04
Send the tracee a
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
to terminate it.
Packit 7cfc04
.RI ( addr
Packit 7cfc04
and
Packit 7cfc04
.I data
Packit 7cfc04
are ignored.)
Packit 7cfc04
.IP
Packit 7cfc04
.I This operation is deprecated; do not use it!
Packit 7cfc04
Instead, send a
Packit 7cfc04
.BR SIGKILL
Packit 7cfc04
directly using
Packit 7cfc04
.BR kill (2)
Packit 7cfc04
or
Packit 7cfc04
.BR tgkill (2).
Packit 7cfc04
The problem with
Packit 7cfc04
.B PTRACE_KILL
Packit 7cfc04
is that it requires the tracee to be in signal-delivery-stop,
Packit 7cfc04
otherwise it may not work
Packit 7cfc04
(i.e., may complete successfully but won't kill the tracee).
Packit 7cfc04
By contrast, sending a
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
directly has no such limitation.
Packit 7cfc04
.\" [Note from Denys Vlasenko:
Packit 7cfc04
.\"     deprecation suggested by Oleg Nesterov. He prefers to deprecate it
Packit 7cfc04
.\"     instead of describing (and needing to support) PTRACE_KILL's quirks.]
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_INTERRUPT " (since Linux 3.4)"
Packit 7cfc04
Stop a tracee.
Packit 7cfc04
If the tracee is running or sleeping in kernel space and
Packit 7cfc04
.B PTRACE_SYSCALL
Packit 7cfc04
is in effect,
Packit 7cfc04
the system call is interrupted and syscall-exit-stop is reported.
Packit 7cfc04
(The interrupted system call is restarted when the tracee is restarted.)
Packit 7cfc04
If the tracee was already stopped by a signal and
Packit 7cfc04
.B PTRACE_LISTEN
Packit 7cfc04
was sent to it,
Packit 7cfc04
the tracee stops with
Packit 7cfc04
.B PTRACE_EVENT_STOP
Packit 7cfc04
and
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
returns the stop signal.
Packit 7cfc04
If any other ptrace-stop is generated at the same time (for example,
Packit 7cfc04
if a signal is sent to the tracee), this ptrace-stop happens.
Packit 7cfc04
If none of the above applies (for example, if the tracee is running in user
Packit 7cfc04
space), it stops with
Packit 7cfc04
.B PTRACE_EVENT_STOP
Packit 7cfc04
with
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
==
Packit 7cfc04
.BR SIGTRAP .
Packit 7cfc04
.B PTRACE_INTERRUPT
Packit 7cfc04
only works on tracees attached by
Packit 7cfc04
.BR PTRACE_SEIZE .
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_ATTACH
Packit 7cfc04
Attach to the process specified in
Packit 7cfc04
.IR pid ,
Packit 7cfc04
making it a tracee of the calling process.
Packit 7cfc04
.\" No longer true (removed by Denys Vlasenko, 2011, who remarks:
Packit 7cfc04
.\"        "I think it isn't true in non-ancient 2.4 and in 2.6/3.x.
Packit 7cfc04
.\"         Basically, it's not true for any Linux in practical use.
Packit 7cfc04
.\" ; the behavior of the tracee is as if it had done a
Packit 7cfc04
.\" .BR PTRACE_TRACEME .
Packit 7cfc04
.\" The calling process actually becomes the parent of the tracee
Packit 7cfc04
.\" process for most purposes (e.g., it will receive
Packit 7cfc04
.\" notification of tracee events and appears in
Packit 7cfc04
.\" .BR ps (1)
Packit 7cfc04
.\" output as the tracee's parent), but a
Packit 7cfc04
.\" .BR getppid (2)
Packit 7cfc04
.\" by the tracee will still return the PID of the original parent.
Packit 7cfc04
The tracee is sent a
Packit 7cfc04
.BR SIGSTOP ,
Packit 7cfc04
but will not necessarily have stopped
Packit 7cfc04
by the completion of this call; use
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
to wait for the tracee to stop.
Packit 7cfc04
See the "Attaching and detaching" subsection for additional information.
Packit 7cfc04
.RI ( addr
Packit 7cfc04
and
Packit 7cfc04
.I data
Packit 7cfc04
are ignored.)
Packit 7cfc04
.IP
Packit 7cfc04
Permission to perform a
Packit 7cfc04
.BR PTRACE_ATTACH
Packit 7cfc04
is governed by a ptrace access mode
Packit 7cfc04
.B PTRACE_MODE_ATTACH_REALCREDS
Packit 7cfc04
check; see below.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SEIZE " (since Linux 3.4)"
Packit 7cfc04
.\"
Packit 7cfc04
.\" Noted by Dmitry Levin:
Packit 7cfc04
.\"
Packit 7cfc04
.\"     PTRACE_SEIZE was introduced by commit v3.1-rc1~308^2~28, but
Packit 7cfc04
.\"     it had to be used along with a temporary flag PTRACE_SEIZE_DEVEL,
Packit 7cfc04
.\"     which was removed later by commit v3.4-rc1~109^2~20.
Packit 7cfc04
.\"
Packit 7cfc04
.\"     That is, [before] v3.4 we had a test mode of PTRACE_SEIZE API,
Packit 7cfc04
.\"     which was not compatible with the current PTRACE_SEIZE API introduced
Packit 7cfc04
.\"     in Linux 3.4.
Packit 7cfc04
.\"
Packit 7cfc04
Attach to the process specified in
Packit 7cfc04
.IR pid ,
Packit 7cfc04
making it a tracee of the calling process.
Packit 7cfc04
Unlike
Packit 7cfc04
.BR PTRACE_ATTACH ,
Packit 7cfc04
.B PTRACE_SEIZE
Packit 7cfc04
does not stop the process.
Packit 7cfc04
Group-stops are reported as
Packit 7cfc04
.B PTRACE_EVENT_STOP
Packit 7cfc04
and
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
returns the stop signal.
Packit 7cfc04
Automatically attached children stop with
Packit 7cfc04
.B PTRACE_EVENT_STOP
Packit 7cfc04
and
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
returns
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
instead of having
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
signal delivered to them.
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
does not deliver an extra
Packit 7cfc04
.BR SIGTRAP .
Packit 7cfc04
Only a
Packit 7cfc04
.BR PTRACE_SEIZE d
Packit 7cfc04
process can accept
Packit 7cfc04
.B PTRACE_INTERRUPT
Packit 7cfc04
and
Packit 7cfc04
.B PTRACE_LISTEN
Packit 7cfc04
commands.
Packit 7cfc04
The "seized" behavior just described is inherited by
Packit 7cfc04
children that are automatically attached using
Packit 7cfc04
.BR PTRACE_O_TRACEFORK ,
Packit 7cfc04
.BR PTRACE_O_TRACEVFORK ,
Packit 7cfc04
and
Packit 7cfc04
.BR PTRACE_O_TRACECLONE .
Packit 7cfc04
.I addr
Packit 7cfc04
must be zero.
Packit 7cfc04
.I data
Packit 7cfc04
contains a bit mask of ptrace options to activate immediately.
Packit 7cfc04
.IP
Packit 7cfc04
Permission to perform a
Packit 7cfc04
.BR PTRACE_SEIZE
Packit 7cfc04
is governed by a ptrace access mode
Packit 7cfc04
.B PTRACE_MODE_ATTACH_REALCREDS
Packit 7cfc04
check; see below.
Packit 7cfc04
.\"
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SECCOMP_GET_FILTER " (since Linux 4.4)"
Packit 7cfc04
.\" commit f8e529ed941ba2bbcbf310b575d968159ce7e895
Packit 7cfc04
This operation allows the tracer to dump the tracee's
Packit 7cfc04
classic BPF filters.
Packit 7cfc04
.IP
Packit 7cfc04
.I addr
Packit 7cfc04
is an integer specifying the index of the filter to be dumped.
Packit 7cfc04
The most recently installed filter has the index 0.
Packit 7cfc04
If
Packit 7cfc04
.I addr
Packit 7cfc04
is greater than the number of installed filters,
Packit 7cfc04
the operation fails with the error
Packit 7cfc04
.BR ENOENT .
Packit 7cfc04
.IP
Packit 7cfc04
.I data
Packit 7cfc04
is either a pointer to a
Packit 7cfc04
.IR "struct sock_filter"
Packit 7cfc04
array that is large enough to store the BPF program,
Packit 7cfc04
or NULL if the program is not to be stored.
Packit 7cfc04
.IP
Packit 7cfc04
Upon success,
Packit 7cfc04
the return value is the number of instructions in the BPF program.
Packit 7cfc04
If
Packit 7cfc04
.I data
Packit 7cfc04
was NULL, then this return value can be used to correctly size the
Packit 7cfc04
.IR "struct sock_filter"
Packit 7cfc04
array passed in a subsequent call.
Packit 7cfc04
.IP
Packit 7cfc04
This operation fails with the error
Packit 7cfc04
.B EACCESS
Packit 7cfc04
if the caller does not have the
Packit 7cfc04
.B CAP_SYS_ADMIN
Packit 7cfc04
capability or if the caller is in strict or filter seccomp mode.
Packit 7cfc04
If the filter referred to by
Packit 7cfc04
.I addr
Packit 7cfc04
is not a classic BPF filter, the operation fails with the error
Packit 7cfc04
.BR EMEDIUMTYPE .
Packit 7cfc04
.IP
Packit 7cfc04
This operation is available if the kernel was configured with both the
Packit 7cfc04
.B CONFIG_SECCOMP_FILTER
Packit 7cfc04
and the
Packit 7cfc04
.B CONFIG_CHECKPOINT_RESTORE
Packit 7cfc04
options.
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_DETACH
Packit 7cfc04
Restart the stopped tracee as for
Packit 7cfc04
.BR PTRACE_CONT ,
Packit 7cfc04
but first detach from it.
Packit 7cfc04
Under Linux, a tracee can be detached in this way regardless
Packit 7cfc04
of which method was used to initiate tracing.
Packit 7cfc04
.RI ( addr
Packit 7cfc04
is ignored.)
Packit 7cfc04
.\"
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_GET_THREAD_AREA " (since Linux 2.6.0)"
Packit 7cfc04
This operation performs a similar task to
Packit 7cfc04
.BR get_thread_area (2).
Packit 7cfc04
It reads the TLS entry in the GDT whose index is given in
Packit 7cfc04
.IR addr ,
Packit 7cfc04
placing a copy of the entry into the
Packit 7cfc04
.IR "struct user_desc"
Packit 7cfc04
pointed to by
Packit 7cfc04
.IR data .
Packit 7cfc04
(By contrast with
Packit 7cfc04
.BR get_thread_area (2),
Packit 7cfc04
the
Packit 7cfc04
.I entry_number
Packit 7cfc04
of the
Packit 7cfc04
.IR "struct user_desc"
Packit 7cfc04
is ignored.)
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_SET_THREAD_AREA " (since Linux 2.6.0)"
Packit 7cfc04
This operation performs a similar task to
Packit 7cfc04
.BR set_thread_area (2).
Packit 7cfc04
It sets the TLS entry in the GDT whose index is given in
Packit 7cfc04
.IR addr ,
Packit 7cfc04
assigning it the data supplied in the
Packit 7cfc04
.IR "struct user_desc"
Packit 7cfc04
pointed to by
Packit 7cfc04
.IR data .
Packit 7cfc04
(By contrast with
Packit 7cfc04
.BR set_thread_area (2),
Packit 7cfc04
the
Packit 7cfc04
.I entry_number
Packit 7cfc04
of the
Packit 7cfc04
.IR "struct user_desc"
Packit 7cfc04
is ignored; in other words,
Packit 7cfc04
this ptrace operation can't be used to allocate a free TLS entry.)
Packit 7cfc04
.\"
Packit 7cfc04
.SS Death under ptrace
Packit 7cfc04
When a (possibly multithreaded) process receives a killing signal
Packit 7cfc04
(one whose disposition is set to
Packit 7cfc04
.B SIG_DFL
Packit 7cfc04
and whose default action is to kill the process),
Packit 7cfc04
all threads exit.
Packit 7cfc04
Tracees report their death to their tracer(s).
Packit 7cfc04
Notification of this event is delivered via
Packit 7cfc04
.BR waitpid (2).
Packit 7cfc04
.PP
Packit 7cfc04
Note that the killing signal will first cause signal-delivery-stop
Packit 7cfc04
(on one tracee only),
Packit 7cfc04
and only after it is injected by the tracer
Packit 7cfc04
(or after it was dispatched to a thread which isn't traced),
Packit 7cfc04
will death from the signal happen on
Packit 7cfc04
.I all
Packit 7cfc04
tracees within a multithreaded process.
Packit 7cfc04
(The term "signal-delivery-stop" is explained below.)
Packit 7cfc04
.PP
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
does not generate signal-delivery-stop and
Packit 7cfc04
therefore the tracer can't suppress it.
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
kills even within system calls
Packit 7cfc04
(syscall-exit-stop is not generated prior to death by
Packit 7cfc04
.BR SIGKILL ).
Packit 7cfc04
The net effect is that
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
always kills the process (all its threads),
Packit 7cfc04
even if some threads of the process are ptraced.
Packit 7cfc04
.PP
Packit 7cfc04
When the tracee calls
Packit 7cfc04
.BR _exit (2),
Packit 7cfc04
it reports its death to its tracer.
Packit 7cfc04
Other threads are not affected.
Packit 7cfc04
.PP
Packit 7cfc04
When any thread executes
Packit 7cfc04
.BR exit_group (2),
Packit 7cfc04
every tracee in its thread group reports its death to its tracer.
Packit 7cfc04
.PP
Packit 7cfc04
If the
Packit 7cfc04
.B PTRACE_O_TRACEEXIT
Packit 7cfc04
option is on,
Packit 7cfc04
.B PTRACE_EVENT_EXIT
Packit 7cfc04
will happen before actual death.
Packit 7cfc04
This applies to exits via
Packit 7cfc04
.BR exit (2),
Packit 7cfc04
.BR exit_group (2),
Packit 7cfc04
and signal deaths (except
Packit 7cfc04
.BR SIGKILL ,
Packit 7cfc04
depending on the kernel version; see BUGS below),
Packit 7cfc04
and when threads are torn down on
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
in a multithreaded process.
Packit 7cfc04
.PP
Packit 7cfc04
The tracer cannot assume that the ptrace-stopped tracee exists.
Packit 7cfc04
There are many scenarios when the tracee may die while stopped (such as
Packit 7cfc04
.BR SIGKILL ).
Packit 7cfc04
Therefore, the tracer must be prepared to handle an
Packit 7cfc04
.B ESRCH
Packit 7cfc04
error on any ptrace operation.
Packit 7cfc04
Unfortunately, the same error is returned if the tracee
Packit 7cfc04
exists but is not ptrace-stopped
Packit 7cfc04
(for commands which require a stopped tracee),
Packit 7cfc04
or if it is not traced by the process which issued the ptrace call.
Packit 7cfc04
The tracer needs to keep track of the stopped/running state of the tracee,
Packit 7cfc04
and interpret
Packit 7cfc04
.B ESRCH
Packit 7cfc04
as "tracee died unexpectedly" only if it knows that the tracee has
Packit 7cfc04
been observed to enter ptrace-stop.
Packit 7cfc04
Note that there is no guarantee that
Packit 7cfc04
.I waitpid(WNOHANG)
Packit 7cfc04
will reliably report the tracee's death status if a
Packit 7cfc04
ptrace operation returned
Packit 7cfc04
.BR ESRCH .
Packit 7cfc04
.I waitpid(WNOHANG)
Packit 7cfc04
may return 0 instead.
Packit 7cfc04
In other words, the tracee may be "not yet fully dead",
Packit 7cfc04
but already refusing ptrace requests.
Packit 7cfc04
.PP
Packit 7cfc04
The tracer can't assume that the tracee
Packit 7cfc04
.I always
Packit 7cfc04
ends its life by reporting
Packit 7cfc04
.I WIFEXITED(status)
Packit 7cfc04
or
Packit 7cfc04
.IR WIFSIGNALED(status) ;
Packit 7cfc04
there are cases where this does not occur.
Packit 7cfc04
For example, if a thread other than thread group leader does an
Packit 7cfc04
.BR execve (2),
Packit 7cfc04
it disappears;
Packit 7cfc04
its PID will never be seen again,
Packit 7cfc04
and any subsequent ptrace stops will be reported under
Packit 7cfc04
the thread group leader's PID.
Packit 7cfc04
.SS Stopped states
Packit 7cfc04
A tracee can be in two states: running or stopped.
Packit 7cfc04
For the purposes of ptrace, a tracee which is blocked in a system call
Packit 7cfc04
(such as
Packit 7cfc04
.BR read (2),
Packit 7cfc04
.BR pause (2),
Packit 7cfc04
etc.)
Packit 7cfc04
is nevertheless considered to be running, even if the tracee is blocked
Packit 7cfc04
for a long time.
Packit 7cfc04
The state of the tracee after
Packit 7cfc04
.BR PTRACE_LISTEN
Packit 7cfc04
is somewhat of a gray area: it is not in any ptrace-stop (ptrace commands
Packit 7cfc04
won't work on it, and it will deliver
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
notifications),
Packit 7cfc04
but it also may be considered "stopped" because
Packit 7cfc04
it is not executing instructions (is not scheduled), and if it was
Packit 7cfc04
in group-stop before
Packit 7cfc04
.BR PTRACE_LISTEN ,
Packit 7cfc04
it will not respond to signals until
Packit 7cfc04
.B SIGCONT
Packit 7cfc04
is received.
Packit 7cfc04
.PP
Packit 7cfc04
There are many kinds of states when the tracee is stopped, and in ptrace
Packit 7cfc04
discussions they are often conflated.
Packit 7cfc04
Therefore, it is important to use precise terms.
Packit 7cfc04
.PP
Packit 7cfc04
In this manual page, any stopped state in which the tracee is ready
Packit 7cfc04
to accept ptrace commands from the tracer is called
Packit 7cfc04
.IR ptrace-stop .
Packit 7cfc04
Ptrace-stops can
Packit 7cfc04
be further subdivided into
Packit 7cfc04
.IR signal-delivery-stop ,
Packit 7cfc04
.IR group-stop ,
Packit 7cfc04
.IR syscall-stop ,
Packit 7cfc04
.IR PTRACE_EVENT stops,
Packit 7cfc04
and so on.
Packit 7cfc04
These stopped states are described in detail below.
Packit 7cfc04
.PP
Packit 7cfc04
When the running tracee enters ptrace-stop, it notifies its tracer using
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
(or one of the other "wait" system calls).
Packit 7cfc04
Most of this manual page assumes that the tracer waits with:
Packit 7cfc04
.PP
Packit 7cfc04
    pid = waitpid(pid_or_minus_1, &status, __WALL);
Packit 7cfc04
.PP
Packit 7cfc04
Ptrace-stopped tracees are reported as returns with
Packit 7cfc04
.I pid
Packit 7cfc04
greater than 0 and
Packit 7cfc04
.I WIFSTOPPED(status)
Packit 7cfc04
true.
Packit 7cfc04
.\" Denys Vlasenko:
Packit 7cfc04
.\"     Do we require __WALL usage, or will just using 0 be ok? (With 0,
Packit 7cfc04
.\"     I am not 100% sure there aren't ugly corner cases.) Are the
Packit 7cfc04
.\"     rules different if user wants to use waitid? Will waitid require
Packit 7cfc04
.\"     WEXITED?
Packit 7cfc04
.\"
Packit 7cfc04
.PP
Packit 7cfc04
The
Packit 7cfc04
.B __WALL
Packit 7cfc04
flag does not include the
Packit 7cfc04
.B WSTOPPED
Packit 7cfc04
and
Packit 7cfc04
.B WEXITED
Packit 7cfc04
flags, but implies their functionality.
Packit 7cfc04
.PP
Packit 7cfc04
Setting the
Packit 7cfc04
.B WCONTINUED
Packit 7cfc04
flag when calling
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
is not recommended: the "continued" state is per-process and
Packit 7cfc04
consuming it can confuse the real parent of the tracee.
Packit 7cfc04
.PP
Packit 7cfc04
Use of the
Packit 7cfc04
.B WNOHANG
Packit 7cfc04
flag may cause
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
to return 0 ("no wait results available yet")
Packit 7cfc04
even if the tracer knows there should be a notification.
Packit 7cfc04
Example:
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
errno = 0;
Packit 7cfc04
ptrace(PTRACE_CONT, pid, 0L, 0L);
Packit 7cfc04
if (errno == ESRCH) {
Packit 7cfc04
    /* tracee is dead */
Packit 7cfc04
    r = waitpid(tracee, &status, __WALL | WNOHANG);
Packit 7cfc04
    /* r can still be 0 here! */
Packit 7cfc04
}
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.\" FIXME .
Packit 7cfc04
.\"     waitid usage? WNOWAIT?
Packit 7cfc04
.\"     describe how wait notifications queue (or not queue)
Packit 7cfc04
.PP
Packit 7cfc04
The following kinds of ptrace-stops exist: signal-delivery-stops,
Packit 7cfc04
group-stops,
Packit 7cfc04
.B PTRACE_EVENT
Packit 7cfc04
stops, syscall-stops.
Packit 7cfc04
They all are reported by
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
with
Packit 7cfc04
.I WIFSTOPPED(status)
Packit 7cfc04
true.
Packit 7cfc04
They may be differentiated by examining the value
Packit 7cfc04
.IR status>>8 ,
Packit 7cfc04
and if there is ambiguity in that value, by querying
Packit 7cfc04
.BR PTRACE_GETSIGINFO .
Packit 7cfc04
(Note: the
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
macro can't be used to perform this examination,
Packit 7cfc04
because it returns the value
Packit 7cfc04
.IR "(status>>8)\ &\ 0xff" .)
Packit 7cfc04
.SS Signal-delivery-stop
Packit 7cfc04
When a (possibly multithreaded) process receives any signal except
Packit 7cfc04
.BR SIGKILL ,
Packit 7cfc04
the kernel selects an arbitrary thread which handles the signal.
Packit 7cfc04
(If the signal is generated with
Packit 7cfc04
.BR tgkill (2),
Packit 7cfc04
the target thread can be explicitly selected by the caller.)
Packit 7cfc04
If the selected thread is traced, it enters signal-delivery-stop.
Packit 7cfc04
At this point, the signal is not yet delivered to the process,
Packit 7cfc04
and can be suppressed by the tracer.
Packit 7cfc04
If the tracer doesn't suppress the signal,
Packit 7cfc04
it passes the signal to the tracee in the next ptrace restart request.
Packit 7cfc04
This second step of signal delivery is called
Packit 7cfc04
.I "signal injection"
Packit 7cfc04
in this manual page.
Packit 7cfc04
Note that if the signal is blocked,
Packit 7cfc04
signal-delivery-stop doesn't happen until the signal is unblocked,
Packit 7cfc04
with the usual exception that
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
can't be blocked.
Packit 7cfc04
.PP
Packit 7cfc04
Signal-delivery-stop is observed by the tracer as
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
returning with
Packit 7cfc04
.I WIFSTOPPED(status)
Packit 7cfc04
true, with the signal returned by
Packit 7cfc04
.IR WSTOPSIG(status) .
Packit 7cfc04
If the signal is
Packit 7cfc04
.BR SIGTRAP ,
Packit 7cfc04
this may be a different kind of ptrace-stop;
Packit 7cfc04
see the "Syscall-stops" and "execve" sections below for details.
Packit 7cfc04
If
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
returns a stopping signal, this may be a group-stop; see below.
Packit 7cfc04
.SS Signal injection and suppression
Packit 7cfc04
After signal-delivery-stop is observed by the tracer,
Packit 7cfc04
the tracer should restart the tracee with the call
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_restart, pid, 0, sig)
Packit 7cfc04
.PP
Packit 7cfc04
where
Packit 7cfc04
.B PTRACE_restart
Packit 7cfc04
is one of the restarting ptrace requests.
Packit 7cfc04
If
Packit 7cfc04
.I sig
Packit 7cfc04
is 0, then a signal is not delivered.
Packit 7cfc04
Otherwise, the signal
Packit 7cfc04
.I sig
Packit 7cfc04
is delivered.
Packit 7cfc04
This operation is called
Packit 7cfc04
.I "signal injection"
Packit 7cfc04
in this manual page, to distinguish it from signal-delivery-stop.
Packit 7cfc04
.PP
Packit 7cfc04
The
Packit 7cfc04
.I sig
Packit 7cfc04
value may be different from the
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
value: the tracer can cause a different signal to be injected.
Packit 7cfc04
.PP
Packit 7cfc04
Note that a suppressed signal still causes system calls to return
Packit 7cfc04
prematurely.
Packit 7cfc04
In this case, system calls will be restarted: the tracer will
Packit 7cfc04
observe the tracee to reexecute the interrupted system call (or
Packit 7cfc04
.BR restart_syscall (2)
Packit 7cfc04
system call for a few system calls which use a different mechanism
Packit 7cfc04
for restarting) if the tracer uses
Packit 7cfc04
.BR PTRACE_SYSCALL .
Packit 7cfc04
Even system calls (such as
Packit 7cfc04
.BR poll (2))
Packit 7cfc04
which are not restartable after signal are restarted after
Packit 7cfc04
signal is suppressed;
Packit 7cfc04
however, kernel bugs exist which cause some system calls to fail with
Packit 7cfc04
.B EINTR
Packit 7cfc04
even though no observable signal is injected to the tracee.
Packit 7cfc04
.PP
Packit 7cfc04
Restarting ptrace commands issued in ptrace-stops other than
Packit 7cfc04
signal-delivery-stop are not guaranteed to inject a signal, even if
Packit 7cfc04
.I sig
Packit 7cfc04
is nonzero.
Packit 7cfc04
No error is reported; a nonzero
Packit 7cfc04
.I sig
Packit 7cfc04
may simply be ignored.
Packit 7cfc04
Ptrace users should not try to "create a new signal" this way: use
Packit 7cfc04
.BR tgkill (2)
Packit 7cfc04
instead.
Packit 7cfc04
.PP
Packit 7cfc04
The fact that signal injection requests may be ignored
Packit 7cfc04
when restarting the tracee after
Packit 7cfc04
ptrace stops that are not signal-delivery-stops
Packit 7cfc04
is a cause of confusion among ptrace users.
Packit 7cfc04
One typical scenario is that the tracer observes group-stop,
Packit 7cfc04
mistakes it for signal-delivery-stop, restarts the tracee with
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_restart, pid, 0, stopsig)
Packit 7cfc04
.PP
Packit 7cfc04
with the intention of injecting
Packit 7cfc04
.IR stopsig ,
Packit 7cfc04
but
Packit 7cfc04
.I stopsig
Packit 7cfc04
gets ignored and the tracee continues to run.
Packit 7cfc04
.PP
Packit 7cfc04
The
Packit 7cfc04
.B SIGCONT
Packit 7cfc04
signal has a side effect of waking up (all threads of)
Packit 7cfc04
a group-stopped process.
Packit 7cfc04
This side effect happens before signal-delivery-stop.
Packit 7cfc04
The tracer can't suppress this side effect (it can
Packit 7cfc04
only suppress signal injection, which only causes the
Packit 7cfc04
.BR SIGCONT
Packit 7cfc04
handler to not be executed in the tracee, if such a handler is installed).
Packit 7cfc04
In fact, waking up from group-stop may be followed by
Packit 7cfc04
signal-delivery-stop for signal(s)
Packit 7cfc04
.I other than
Packit 7cfc04
.BR SIGCONT ,
Packit 7cfc04
if they were pending when
Packit 7cfc04
.B SIGCONT
Packit 7cfc04
was delivered.
Packit 7cfc04
In other words,
Packit 7cfc04
.B SIGCONT
Packit 7cfc04
may be not the first signal observed by the tracee after it was sent.
Packit 7cfc04
.PP
Packit 7cfc04
Stopping signals cause (all threads of) a process to enter group-stop.
Packit 7cfc04
This side effect happens after signal injection, and therefore can be
Packit 7cfc04
suppressed by the tracer.
Packit 7cfc04
.PP
Packit 7cfc04
In Linux 2.4 and earlier, the
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
signal can't be injected.
Packit 7cfc04
.\" In the Linux 2.4 sources, in arch/i386/kernel/signal.c::do_signal(),
Packit 7cfc04
.\" there is:
Packit 7cfc04
.\"
Packit 7cfc04
.\"             /* The debugger continued.  Ignore SIGSTOP.  */
Packit 7cfc04
.\"             if (signr == SIGSTOP)
Packit 7cfc04
.\"                     continue;
Packit 7cfc04
.PP
Packit 7cfc04
.B PTRACE_GETSIGINFO
Packit 7cfc04
can be used to retrieve a
Packit 7cfc04
.I siginfo_t
Packit 7cfc04
structure which corresponds to the delivered signal.
Packit 7cfc04
.B PTRACE_SETSIGINFO
Packit 7cfc04
may be used to modify it.
Packit 7cfc04
If
Packit 7cfc04
.B PTRACE_SETSIGINFO
Packit 7cfc04
has been used to alter
Packit 7cfc04
.IR siginfo_t ,
Packit 7cfc04
the
Packit 7cfc04
.I si_signo
Packit 7cfc04
field and the
Packit 7cfc04
.I sig
Packit 7cfc04
parameter in the restarting command must match,
Packit 7cfc04
otherwise the result is undefined.
Packit 7cfc04
.SS Group-stop
Packit 7cfc04
When a (possibly multithreaded) process receives a stopping signal,
Packit 7cfc04
all threads stop.
Packit 7cfc04
If some threads are traced, they enter a group-stop.
Packit 7cfc04
Note that the stopping signal will first cause signal-delivery-stop
Packit 7cfc04
(on one tracee only), and only after it is injected by the tracer
Packit 7cfc04
(or after it was dispatched to a thread which isn't traced),
Packit 7cfc04
will group-stop be initiated on
Packit 7cfc04
.I all
Packit 7cfc04
tracees within the multithreaded process.
Packit 7cfc04
As usual, every tracee reports its group-stop separately
Packit 7cfc04
to the corresponding tracer.
Packit 7cfc04
.PP
Packit 7cfc04
Group-stop is observed by the tracer as
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
returning with
Packit 7cfc04
.I WIFSTOPPED(status)
Packit 7cfc04
true, with the stopping signal available via
Packit 7cfc04
.IR WSTOPSIG(status) .
Packit 7cfc04
The same result is returned by some other classes of ptrace-stops,
Packit 7cfc04
therefore the recommended practice is to perform the call
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo)
Packit 7cfc04
.PP
Packit 7cfc04
The call can be avoided if the signal is not
Packit 7cfc04
.BR SIGSTOP ,
Packit 7cfc04
.BR SIGTSTP ,
Packit 7cfc04
.BR SIGTTIN ,
Packit 7cfc04
or
Packit 7cfc04
.BR SIGTTOU ;
Packit 7cfc04
only these four signals are stopping signals.
Packit 7cfc04
If the tracer sees something else, it can't be a group-stop.
Packit 7cfc04
Otherwise, the tracer needs to call
Packit 7cfc04
.BR PTRACE_GETSIGINFO .
Packit 7cfc04
If
Packit 7cfc04
.B PTRACE_GETSIGINFO
Packit 7cfc04
fails with
Packit 7cfc04
.BR EINVAL ,
Packit 7cfc04
then it is definitely a group-stop.
Packit 7cfc04
(Other failure codes are possible, such as
Packit 7cfc04
.B ESRCH
Packit 7cfc04
("no such process") if a
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
killed the tracee.)
Packit 7cfc04
.PP
Packit 7cfc04
If tracee was attached using
Packit 7cfc04
.BR PTRACE_SEIZE ,
Packit 7cfc04
group-stop is indicated by
Packit 7cfc04
.BR PTRACE_EVENT_STOP :
Packit 7cfc04
.IR "status>>16 == PTRACE_EVENT_STOP" .
Packit 7cfc04
This allows detection of group-stops
Packit 7cfc04
without requiring an extra
Packit 7cfc04
.B PTRACE_GETSIGINFO
Packit 7cfc04
call.
Packit 7cfc04
.PP
Packit 7cfc04
As of Linux 2.6.38,
Packit 7cfc04
after the tracer sees the tracee ptrace-stop and until it
Packit 7cfc04
restarts or kills it, the tracee will not run,
Packit 7cfc04
and will not send notifications (except
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
death) to the tracer, even if the tracer enters into another
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
call.
Packit 7cfc04
.PP
Packit 7cfc04
The kernel behavior described in the previous paragraph
Packit 7cfc04
causes a problem with transparent handling of stopping signals.
Packit 7cfc04
If the tracer restarts the tracee after group-stop,
Packit 7cfc04
the stopping signal
Packit 7cfc04
is effectively ignored\(emthe tracee doesn't remain stopped, it runs.
Packit 7cfc04
If the tracer doesn't restart the tracee before entering into the next
Packit 7cfc04
.BR waitpid (2),
Packit 7cfc04
future
Packit 7cfc04
.B SIGCONT
Packit 7cfc04
signals will not be reported to the tracer;
Packit 7cfc04
this would cause the
Packit 7cfc04
.B SIGCONT
Packit 7cfc04
signals to have no effect on the tracee.
Packit 7cfc04
.PP
Packit 7cfc04
Since Linux 3.4, there is a method to overcome this problem: instead of
Packit 7cfc04
.BR PTRACE_CONT ,
Packit 7cfc04
a
Packit 7cfc04
.B PTRACE_LISTEN
Packit 7cfc04
command can be used to restart a tracee in a way where it does not execute,
Packit 7cfc04
but waits for a new event which it can report via
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
(such as when
Packit 7cfc04
it is restarted by a
Packit 7cfc04
.BR SIGCONT ).
Packit 7cfc04
.SS PTRACE_EVENT stops
Packit 7cfc04
If the tracer sets
Packit 7cfc04
.B PTRACE_O_TRACE_*
Packit 7cfc04
options, the tracee will enter ptrace-stops called
Packit 7cfc04
.B PTRACE_EVENT
Packit 7cfc04
stops.
Packit 7cfc04
.PP
Packit 7cfc04
.B PTRACE_EVENT
Packit 7cfc04
stops are observed by the tracer as
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
returning with
Packit 7cfc04
.IR WIFSTOPPED(status) ,
Packit 7cfc04
and
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
returns
Packit 7cfc04
.BR SIGTRAP .
Packit 7cfc04
An additional bit is set in the higher byte of the status word:
Packit 7cfc04
the value
Packit 7cfc04
.I status>>8
Packit 7cfc04
will be
Packit 7cfc04
.PP
Packit 7cfc04
    (SIGTRAP | PTRACE_EVENT_foo << 8).
Packit 7cfc04
.PP
Packit 7cfc04
The following events exist:
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_EVENT_VFORK
Packit 7cfc04
Stop before return from
Packit 7cfc04
.BR vfork (2)
Packit 7cfc04
or
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
with the
Packit 7cfc04
.B CLONE_VFORK
Packit 7cfc04
flag.
Packit 7cfc04
When the tracee is continued after this stop, it will wait for child to
Packit 7cfc04
exit/exec before continuing its execution
Packit 7cfc04
(in other words, the usual behavior on
Packit 7cfc04
.BR vfork (2)).
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_EVENT_FORK
Packit 7cfc04
Stop before return from
Packit 7cfc04
.BR fork (2)
Packit 7cfc04
or
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
with the exit signal set to
Packit 7cfc04
.BR SIGCHLD .
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_EVENT_CLONE
Packit 7cfc04
Stop before return from
Packit 7cfc04
.BR clone (2).
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_EVENT_VFORK_DONE
Packit 7cfc04
Stop before return from
Packit 7cfc04
.BR vfork (2)
Packit 7cfc04
or
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
with the
Packit 7cfc04
.B CLONE_VFORK
Packit 7cfc04
flag,
Packit 7cfc04
but after the child unblocked this tracee by exiting or execing.
Packit 7cfc04
.PP
Packit 7cfc04
For all four stops described above,
Packit 7cfc04
the stop occurs in the parent (i.e., the tracee),
Packit 7cfc04
not in the newly created thread.
Packit 7cfc04
.BR PTRACE_GETEVENTMSG
Packit 7cfc04
can be used to retrieve the new thread's ID.
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_EVENT_EXEC
Packit 7cfc04
Stop before return from
Packit 7cfc04
.BR execve (2).
Packit 7cfc04
Since Linux 3.0,
Packit 7cfc04
.BR PTRACE_GETEVENTMSG
Packit 7cfc04
returns the former thread ID.
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_EVENT_EXIT
Packit 7cfc04
Stop before exit (including death from
Packit 7cfc04
.BR exit_group (2)),
Packit 7cfc04
signal death, or exit caused by
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
in a multithreaded process.
Packit 7cfc04
.B PTRACE_GETEVENTMSG
Packit 7cfc04
returns the exit status.
Packit 7cfc04
Registers can be examined
Packit 7cfc04
(unlike when "real" exit happens).
Packit 7cfc04
The tracee is still alive; it needs to be
Packit 7cfc04
.BR PTRACE_CONT ed
Packit 7cfc04
or
Packit 7cfc04
.BR PTRACE_DETACH ed
Packit 7cfc04
to finish exiting.
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_EVENT_STOP
Packit 7cfc04
Stop induced by
Packit 7cfc04
.B PTRACE_INTERRUPT
Packit 7cfc04
command, or group-stop, or initial ptrace-stop when a new child is attached
Packit 7cfc04
(only if attached using
Packit 7cfc04
.BR PTRACE_SEIZE ).
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_EVENT_SECCOMP
Packit 7cfc04
Stop triggered by a
Packit 7cfc04
.BR seccomp (2)
Packit 7cfc04
rule on tracee syscall entry when
Packit 7cfc04
.BR PTRACE_O_TRACESECCOMP
Packit 7cfc04
has been set by the tracer.
Packit 7cfc04
The seccomp event message data (from the
Packit 7cfc04
.BR SECCOMP_RET_DATA
Packit 7cfc04
portion of the seccomp filter rule) can be retrieved with
Packit 7cfc04
.BR PTRACE_GETEVENTMSG .
Packit 7cfc04
The semantics of this stop are described in
Packit 7cfc04
detail in a separate section below.
Packit 7cfc04
.PP
Packit 7cfc04
.B PTRACE_GETSIGINFO
Packit 7cfc04
on
Packit 7cfc04
.B PTRACE_EVENT
Packit 7cfc04
stops returns
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
in
Packit 7cfc04
.IR si_signo ,
Packit 7cfc04
with
Packit 7cfc04
.I si_code
Packit 7cfc04
set to
Packit 7cfc04
.IR "(event<<8)\ |\ SIGTRAP" .
Packit 7cfc04
.SS Syscall-stops
Packit 7cfc04
If the tracee was restarted by
Packit 7cfc04
.BR PTRACE_SYSCALL
Packit 7cfc04
or
Packit 7cfc04
.BR PTRACE_SYSEMU ,
Packit 7cfc04
the tracee enters
Packit 7cfc04
syscall-enter-stop just prior to entering any system call (which
Packit 7cfc04
will not be executed if the restart was using
Packit 7cfc04
.BR PTRACE_SYSEMU ,
Packit 7cfc04
regardless of any change made to registers at this point or how the
Packit 7cfc04
tracee is restarted after this stop).
Packit 7cfc04
No matter which method caused the syscall-entry-stop,
Packit 7cfc04
if the tracer restarts the tracee with
Packit 7cfc04
.BR PTRACE_SYSCALL ,
Packit 7cfc04
the tracee enters syscall-exit-stop when the system call is finished,
Packit 7cfc04
or if it is interrupted by a signal.
Packit 7cfc04
(That is, signal-delivery-stop never happens between syscall-enter-stop
Packit 7cfc04
and syscall-exit-stop; it happens
Packit 7cfc04
.I after
Packit 7cfc04
syscall-exit-stop.).
Packit 7cfc04
If the tracee is continued using any other method (including
Packit 7cfc04
.BR PTRACE_SYSEMU ),
Packit 7cfc04
no syscall-exit-stop occurs.
Packit 7cfc04
Note that all mentions
Packit 7cfc04
.BR PTRACE_SYSEMU
Packit 7cfc04
apply equally to
Packit 7cfc04
.BR PTRACE_SYSEMU_SINGLESTEP.
Packit 7cfc04
.PP
Packit 7cfc04
However, even if the tracee was continued using
Packit 7cfc04
.BR PTRACE_SYSCALL
Packit 7cfc04
, it is not guaranteed that the next stop will be a syscall-exit-stop.
Packit 7cfc04
Other possibilities are that the tracee may stop in a
Packit 7cfc04
.B PTRACE_EVENT
Packit 7cfc04
stop (including seccomp stops), exit (if it entered
Packit 7cfc04
.BR _exit (2)
Packit 7cfc04
or
Packit 7cfc04
.BR exit_group (2)),
Packit 7cfc04
be killed by
Packit 7cfc04
.BR SIGKILL ,
Packit 7cfc04
or die silently (if it is a thread group leader, the
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
happened in another thread,
Packit 7cfc04
and that thread is not traced by the same tracer;
Packit 7cfc04
this situation is discussed later).
Packit 7cfc04
.PP
Packit 7cfc04
Syscall-enter-stop and syscall-exit-stop are observed by the tracer as
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
returning with
Packit 7cfc04
.I WIFSTOPPED(status)
Packit 7cfc04
true, and
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
giving
Packit 7cfc04
.BR SIGTRAP .
Packit 7cfc04
If the
Packit 7cfc04
.B PTRACE_O_TRACESYSGOOD
Packit 7cfc04
option was set by the tracer, then
Packit 7cfc04
.I WSTOPSIG(status)
Packit 7cfc04
will give the value
Packit 7cfc04
.IR "(SIGTRAP\ |\ 0x80)" .
Packit 7cfc04
.PP
Packit 7cfc04
Syscall-stops can be distinguished from signal-delivery-stop with
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
by querying
Packit 7cfc04
.BR PTRACE_GETSIGINFO
Packit 7cfc04
for the following cases:
Packit 7cfc04
.TP
Packit 7cfc04
.IR si_code " <= 0"
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
was delivered as a result of a user-space action,
Packit 7cfc04
for example, a system call
Packit 7cfc04
.RB ( tgkill (2),
Packit 7cfc04
.BR kill (2),
Packit 7cfc04
.BR sigqueue (3),
Packit 7cfc04
etc.),
Packit 7cfc04
expiration of a POSIX timer,
Packit 7cfc04
change of state on a POSIX message queue,
Packit 7cfc04
or completion of an asynchronous I/O request.
Packit 7cfc04
.TP
Packit 7cfc04
.IR si_code " == SI_KERNEL (0x80)"
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
was sent by the kernel.
Packit 7cfc04
.TP
Packit 7cfc04
.IR si_code " == SIGTRAP or " si_code " == (SIGTRAP|0x80)"
Packit 7cfc04
This is a syscall-stop.
Packit 7cfc04
.PP
Packit 7cfc04
However, syscall-stops happen very often (twice per system call),
Packit 7cfc04
and performing
Packit 7cfc04
.B PTRACE_GETSIGINFO
Packit 7cfc04
for every syscall-stop may be somewhat expensive.
Packit 7cfc04
.PP
Packit 7cfc04
Some architectures allow the cases to be distinguished
Packit 7cfc04
by examining registers.
Packit 7cfc04
For example, on x86,
Packit 7cfc04
.I rax
Packit 7cfc04
==
Packit 7cfc04
.RB - ENOSYS
Packit 7cfc04
in syscall-enter-stop.
Packit 7cfc04
Since
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
(like any other signal) always happens
Packit 7cfc04
.I after
Packit 7cfc04
syscall-exit-stop,
Packit 7cfc04
and at this point
Packit 7cfc04
.I rax
Packit 7cfc04
almost never contains
Packit 7cfc04
.RB - ENOSYS ,
Packit 7cfc04
the
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
looks like "syscall-stop which is not syscall-enter-stop";
Packit 7cfc04
in other words, it looks like a
Packit 7cfc04
"stray syscall-exit-stop" and can be detected this way.
Packit 7cfc04
But such detection is fragile and is best avoided.
Packit 7cfc04
.PP
Packit 7cfc04
Using the
Packit 7cfc04
.B PTRACE_O_TRACESYSGOOD
Packit 7cfc04
option is the recommended method to distinguish syscall-stops
Packit 7cfc04
from other kinds of ptrace-stops,
Packit 7cfc04
since it is reliable and does not incur a performance penalty.
Packit 7cfc04
.PP
Packit 7cfc04
Syscall-enter-stop and syscall-exit-stop are
Packit 7cfc04
indistinguishable from each other by the tracer.
Packit 7cfc04
The tracer needs to keep track of the sequence of
Packit 7cfc04
ptrace-stops in order to not misinterpret syscall-enter-stop as
Packit 7cfc04
syscall-exit-stop or vice versa.
Packit 7cfc04
In general, a syscall-enter-stop is
Packit 7cfc04
always followed by syscall-exit-stop,
Packit 7cfc04
.B PTRACE_EVENT
Packit 7cfc04
stop, or the tracee's death;
Packit 7cfc04
no other kinds of ptrace-stop can occur in between.
Packit 7cfc04
However, note that seccomp stops (see below) can cause syscall-exit-stops,
Packit 7cfc04
without preceding syscall-entry-stops.
Packit 7cfc04
If seccomp is in use, care needs
Packit 7cfc04
to be taken not to misinterpret such stops as syscall-entry-stops.
Packit 7cfc04
.PP
Packit 7cfc04
If after syscall-enter-stop,
Packit 7cfc04
the tracer uses a restarting command other than
Packit 7cfc04
.BR PTRACE_SYSCALL ,
Packit 7cfc04
syscall-exit-stop is not generated.
Packit 7cfc04
.PP
Packit 7cfc04
.B PTRACE_GETSIGINFO
Packit 7cfc04
on syscall-stops returns
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
in
Packit 7cfc04
.IR si_signo ,
Packit 7cfc04
with
Packit 7cfc04
.I si_code
Packit 7cfc04
set to
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
or
Packit 7cfc04
.IR (SIGTRAP|0x80) .
Packit 7cfc04
.\"
Packit 7cfc04
.SS PTRACE_EVENT_SECCOMP stops (Linux 3.5 to 4.7)
Packit 7cfc04
The behavior of
Packit 7cfc04
.BR PTRACE_EVENT_SECCOMP
Packit 7cfc04
stops and their interaction with other kinds
Packit 7cfc04
of ptrace stops has changed between kernel versions.
Packit 7cfc04
This documents the behavior
Packit 7cfc04
from their introduction until Linux 4.7 (inclusive).
Packit 7cfc04
The behavior in later kernel versions is documented in the next section.
Packit 7cfc04
.PP
Packit 7cfc04
A
Packit 7cfc04
.BR PTRACE_EVENT_SECCOMP
Packit 7cfc04
stop occurs whenever a
Packit 7cfc04
.BR SECCOMP_RET_TRACE
Packit 7cfc04
rule is triggered.
Packit 7cfc04
This is independent of which methods was used to restart the system call.
Packit 7cfc04
Notably, seccomp still runs even if the tracee was restarted using
Packit 7cfc04
.BR PTRACE_SYSEMU
Packit 7cfc04
and this system call is unconditionally skipped.
Packit 7cfc04
.PP
Packit 7cfc04
Restarts from this stop will behave as if the stop had occurred right
Packit 7cfc04
before the system call in question.
Packit 7cfc04
In particular, both
Packit 7cfc04
.BR PTRACE_SYSCALL
Packit 7cfc04
and
Packit 7cfc04
.BR PTRACE_SYSEMU
Packit 7cfc04
will normally cause a subsequent syscall-entry-stop.
Packit 7cfc04
However, if after the
Packit 7cfc04
.BR PTRACE_EVENT_SECCOMP
Packit 7cfc04
the system call number is negative,
Packit 7cfc04
both the syscall-entry-stop and the system call itself will be skipped.
Packit 7cfc04
This means that if the system call number is negative after a
Packit 7cfc04
.BR PTRACE_EVENT_SECCOMP
Packit 7cfc04
and the tracee is restarted using
Packit 7cfc04
.BR PTRACE_SYSCALL,
Packit 7cfc04
the next observed stop will be a syscall-exit-stop,
Packit 7cfc04
rather than the syscall-entry-stop that might have been expected.
Packit 7cfc04
.\"
Packit 7cfc04
.SS PTRACE_EVENT_SECCOMP stops (since Linux 4.8)
Packit 7cfc04
Starting with Linux 4.8,
Packit 7cfc04
.\" commit 93e35efb8de45393cf61ed07f7b407629bf698ea
Packit 7cfc04
the
Packit 7cfc04
.BR PTRACE_EVENT_SECCOMP
Packit 7cfc04
stop was reordered to occur between syscall-entry-stop and
Packit 7cfc04
syscall-exit-stop.
Packit 7cfc04
Note that seccomp no longer runs (and no
Packit 7cfc04
.B PTRACE_EVENT_SECCOMP
Packit 7cfc04
will be reported) if the system call is skipped due to
Packit 7cfc04
.BR PTRACE_SYSEMU .
Packit 7cfc04
.PP
Packit 7cfc04
Functionally, a
Packit 7cfc04
.B PTRACE_EVENT_SECCOMP
Packit 7cfc04
stop functions comparably
Packit 7cfc04
to a syscall-entry-stop (i.e., continuations using
Packit 7cfc04
.BR PTRACE_SYSCALL
Packit 7cfc04
will cause syscall-exit-stops,
Packit 7cfc04
the system call number may be changed and any other modified registers
Packit 7cfc04
are visible to the to-be-executed system call as well).
Packit 7cfc04
Note that there may be,
Packit 7cfc04
but need not have been a preceding syscall-entry-stop.
Packit 7cfc04
.PP
Packit 7cfc04
After a
Packit 7cfc04
.BR PTRACE_EVENT_SECCOMP
Packit 7cfc04
stop, seccomp will be rerun, with a
Packit 7cfc04
.BR SECCOMP_RET_TRACE
Packit 7cfc04
rule now functioning the same as a
Packit 7cfc04
.BR SECCOMP_RET_ALLOW .
Packit 7cfc04
Specifically, this means that if registers are not modified during the
Packit 7cfc04
.BR PTRACE_EVENT_SECCOMP
Packit 7cfc04
stop, the system call will then be allowed.
Packit 7cfc04
.\"
Packit 7cfc04
.SS PTRACE_SINGLESTEP stops
Packit 7cfc04
[Details of these kinds of stops are yet to be documented.]
Packit 7cfc04
.\"
Packit 7cfc04
.\" FIXME .
Packit 7cfc04
.\" document stops occurring with PTRACE_SINGLESTEP
Packit 7cfc04
.\"
Packit 7cfc04
.SS Informational and restarting ptrace commands
Packit 7cfc04
Most ptrace commands (all except
Packit 7cfc04
.BR PTRACE_ATTACH ,
Packit 7cfc04
.BR PTRACE_SEIZE ,
Packit 7cfc04
.BR PTRACE_TRACEME ,
Packit 7cfc04
.BR PTRACE_INTERRUPT ,
Packit 7cfc04
and
Packit 7cfc04
.BR PTRACE_KILL )
Packit 7cfc04
require the tracee to be in a ptrace-stop, otherwise they fail with
Packit 7cfc04
.BR ESRCH .
Packit 7cfc04
.PP
Packit 7cfc04
When the tracee is in ptrace-stop,
Packit 7cfc04
the tracer can read and write data to
Packit 7cfc04
the tracee using informational commands.
Packit 7cfc04
These commands leave the tracee in ptrace-stopped state:
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
ptrace(PTRACE_PEEKTEXT/PEEKDATA/PEEKUSER, pid, addr, 0);
Packit 7cfc04
ptrace(PTRACE_POKETEXT/POKEDATA/POKEUSER, pid, addr, long_val);
Packit 7cfc04
ptrace(PTRACE_GETREGS/GETFPREGS, pid, 0, &struct);
Packit 7cfc04
ptrace(PTRACE_SETREGS/SETFPREGS, pid, 0, &struct);
Packit 7cfc04
ptrace(PTRACE_GETREGSET, pid, NT_foo, &iov;;
Packit 7cfc04
ptrace(PTRACE_SETREGSET, pid, NT_foo, &iov;;
Packit 7cfc04
ptrace(PTRACE_GETSIGINFO, pid, 0, &siginfo);
Packit 7cfc04
ptrace(PTRACE_SETSIGINFO, pid, 0, &siginfo);
Packit 7cfc04
ptrace(PTRACE_GETEVENTMSG, pid, 0, &long_var);
Packit 7cfc04
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags);
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
Note that some errors are not reported.
Packit 7cfc04
For example, setting signal information
Packit 7cfc04
.RI ( siginfo )
Packit 7cfc04
may have no effect in some ptrace-stops, yet the call may succeed
Packit 7cfc04
(return 0 and not set
Packit 7cfc04
.IR errno );
Packit 7cfc04
querying
Packit 7cfc04
.B PTRACE_GETEVENTMSG
Packit 7cfc04
may succeed and return some random value if current ptrace-stop
Packit 7cfc04
is not documented as returning a meaningful event message.
Packit 7cfc04
.PP
Packit 7cfc04
The call
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_flags);
Packit 7cfc04
.PP
Packit 7cfc04
affects one tracee.
Packit 7cfc04
The tracee's current flags are replaced.
Packit 7cfc04
Flags are inherited by new tracees created and "auto-attached" via active
Packit 7cfc04
.BR PTRACE_O_TRACEFORK ,
Packit 7cfc04
.BR PTRACE_O_TRACEVFORK ,
Packit 7cfc04
or
Packit 7cfc04
.BR PTRACE_O_TRACECLONE
Packit 7cfc04
options.
Packit 7cfc04
.PP
Packit 7cfc04
Another group of commands makes the ptrace-stopped tracee run.
Packit 7cfc04
They have the form:
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(cmd, pid, 0, sig);
Packit 7cfc04
.PP
Packit 7cfc04
where
Packit 7cfc04
.I cmd
Packit 7cfc04
is
Packit 7cfc04
.BR PTRACE_CONT ,
Packit 7cfc04
.BR PTRACE_LISTEN ,
Packit 7cfc04
.BR PTRACE_DETACH ,
Packit 7cfc04
.BR PTRACE_SYSCALL ,
Packit 7cfc04
.BR PTRACE_SINGLESTEP ,
Packit 7cfc04
.BR PTRACE_SYSEMU ,
Packit 7cfc04
or
Packit 7cfc04
.BR PTRACE_SYSEMU_SINGLESTEP .
Packit 7cfc04
If the tracee is in signal-delivery-stop,
Packit 7cfc04
.I sig
Packit 7cfc04
is the signal to be injected (if it is nonzero).
Packit 7cfc04
Otherwise,
Packit 7cfc04
.I sig
Packit 7cfc04
may be ignored.
Packit 7cfc04
(When restarting a tracee from a ptrace-stop other than signal-delivery-stop,
Packit 7cfc04
recommended practice is to always pass 0 in
Packit 7cfc04
.IR sig .)
Packit 7cfc04
.SS Attaching and detaching
Packit 7cfc04
A thread can be attached to the tracer using the call
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_ATTACH, pid, 0, 0);
Packit 7cfc04
.PP
Packit 7cfc04
or
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_SEIZE, pid, 0, PTRACE_O_flags);
Packit 7cfc04
.PP
Packit 7cfc04
.B PTRACE_ATTACH
Packit 7cfc04
sends
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
to this thread.
Packit 7cfc04
If the tracer wants this
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
to have no effect, it needs to suppress it.
Packit 7cfc04
Note that if other signals are concurrently sent to
Packit 7cfc04
this thread during attach,
Packit 7cfc04
the tracer may see the tracee enter signal-delivery-stop
Packit 7cfc04
with other signal(s) first!
Packit 7cfc04
The usual practice is to reinject these signals until
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
is seen, then suppress
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
injection.
Packit 7cfc04
The design bug here is that a ptrace attach and a concurrently delivered
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
may race and the concurrent
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
may be lost.
Packit 7cfc04
.\"
Packit 7cfc04
.\" FIXME Describe how to attach to a thread which is already group-stopped.
Packit 7cfc04
.PP
Packit 7cfc04
Since attaching sends
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
and the tracer usually suppresses it, this may cause a stray
Packit 7cfc04
.B EINTR
Packit 7cfc04
return from the currently executing system call in the tracee,
Packit 7cfc04
as described in the "Signal injection and suppression" section.
Packit 7cfc04
.PP
Packit 7cfc04
Since Linux 3.4,
Packit 7cfc04
.B PTRACE_SEIZE
Packit 7cfc04
can be used instead of
Packit 7cfc04
.BR PTRACE_ATTACH .
Packit 7cfc04
.B PTRACE_SEIZE
Packit 7cfc04
does not stop the attached process.
Packit 7cfc04
If you need to stop
Packit 7cfc04
it after attach (or at any other time) without sending it any signals,
Packit 7cfc04
use
Packit 7cfc04
.B PTRACE_INTERRUPT
Packit 7cfc04
command.
Packit 7cfc04
.PP
Packit 7cfc04
The request
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_TRACEME, 0, 0, 0);
Packit 7cfc04
.PP
Packit 7cfc04
turns the calling thread into a tracee.
Packit 7cfc04
The thread continues to run (doesn't enter ptrace-stop).
Packit 7cfc04
A common practice is to follow the
Packit 7cfc04
.B PTRACE_TRACEME
Packit 7cfc04
with
Packit 7cfc04
.PP
Packit 7cfc04
    raise(SIGSTOP);
Packit 7cfc04
.PP
Packit 7cfc04
and allow the parent (which is our tracer now) to observe our
Packit 7cfc04
signal-delivery-stop.
Packit 7cfc04
.PP
Packit 7cfc04
If the
Packit 7cfc04
.BR PTRACE_O_TRACEFORK ,
Packit 7cfc04
.BR PTRACE_O_TRACEVFORK ,
Packit 7cfc04
or
Packit 7cfc04
.BR PTRACE_O_TRACECLONE
Packit 7cfc04
options are in effect, then children created by, respectively,
Packit 7cfc04
.BR vfork (2)
Packit 7cfc04
or
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
with the
Packit 7cfc04
.B CLONE_VFORK
Packit 7cfc04
flag,
Packit 7cfc04
.BR fork (2)
Packit 7cfc04
or
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
with the exit signal set to
Packit 7cfc04
.BR SIGCHLD ,
Packit 7cfc04
and other kinds of
Packit 7cfc04
.BR clone (2),
Packit 7cfc04
are automatically attached to the same tracer which traced their parent.
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
is delivered to the children, causing them to enter
Packit 7cfc04
signal-delivery-stop after they exit the system call which created them.
Packit 7cfc04
.PP
Packit 7cfc04
Detaching of the tracee is performed by:
Packit 7cfc04
.PP
Packit 7cfc04
    ptrace(PTRACE_DETACH, pid, 0, sig);
Packit 7cfc04
.PP
Packit 7cfc04
.B PTRACE_DETACH
Packit 7cfc04
is a restarting operation;
Packit 7cfc04
therefore it requires the tracee to be in ptrace-stop.
Packit 7cfc04
If the tracee is in signal-delivery-stop, a signal can be injected.
Packit 7cfc04
Otherwise, the
Packit 7cfc04
.I sig
Packit 7cfc04
parameter may be silently ignored.
Packit 7cfc04
.PP
Packit 7cfc04
If the tracee is running when the tracer wants to detach it,
Packit 7cfc04
the usual solution is to send
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
(using
Packit 7cfc04
.BR tgkill (2),
Packit 7cfc04
to make sure it goes to the correct thread),
Packit 7cfc04
wait for the tracee to stop in signal-delivery-stop for
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
and then detach it (suppressing
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
injection).
Packit 7cfc04
A design bug is that this can race with concurrent
Packit 7cfc04
.BR SIGSTOP s.
Packit 7cfc04
Another complication is that the tracee may enter other ptrace-stops
Packit 7cfc04
and needs to be restarted and waited for again, until
Packit 7cfc04
.B SIGSTOP
Packit 7cfc04
is seen.
Packit 7cfc04
Yet another complication is to be sure that
Packit 7cfc04
the tracee is not already ptrace-stopped,
Packit 7cfc04
because no signal delivery happens while it is\(emnot even
Packit 7cfc04
.BR SIGSTOP .
Packit 7cfc04
.\" FIXME Describe how to detach from a group-stopped tracee so that it
Packit 7cfc04
.\" doesn't run, but continues to wait for SIGCONT.
Packit 7cfc04
.PP
Packit 7cfc04
If the tracer dies, all tracees are automatically detached and restarted,
Packit 7cfc04
unless they were in group-stop.
Packit 7cfc04
Handling of restart from group-stop is currently buggy,
Packit 7cfc04
but the "as planned" behavior is to leave tracee stopped and waiting for
Packit 7cfc04
.BR SIGCONT .
Packit 7cfc04
If the tracee is restarted from signal-delivery-stop,
Packit 7cfc04
the pending signal is injected.
Packit 7cfc04
.SS execve(2) under ptrace
Packit 7cfc04
.\" clone(2) CLONE_THREAD says:
Packit 7cfc04
.\"     If  any  of the threads in a thread group performs an execve(2),
Packit 7cfc04
.\"     then all threads other than the thread group leader are terminated,
Packit 7cfc04
.\"     and the new program is executed in the thread group leader.
Packit 7cfc04
.\"
Packit 7cfc04
When one thread in a multithreaded process calls
Packit 7cfc04
.BR execve (2),
Packit 7cfc04
the kernel destroys all other threads in the process,
Packit 7cfc04
.\" In kernel 3.1 sources, see fs/exec.c::de_thread()
Packit 7cfc04
and resets the thread ID of the execing thread to the
Packit 7cfc04
thread group ID (process ID).
Packit 7cfc04
(Or, to put things another way, when a multithreaded process does an
Packit 7cfc04
.BR execve (2),
Packit 7cfc04
at completion of the call, it appears as though the
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
occurred in the thread group leader, regardless of which thread did the
Packit 7cfc04
.BR execve (2).)
Packit 7cfc04
This resetting of the thread ID looks very confusing to tracers:
Packit 7cfc04
.IP * 3
Packit 7cfc04
All other threads stop in
Packit 7cfc04
.B PTRACE_EVENT_EXIT
Packit 7cfc04
stop, if the
Packit 7cfc04
.BR PTRACE_O_TRACEEXIT
Packit 7cfc04
option was turned on.
Packit 7cfc04
Then all other threads except the thread group leader report
Packit 7cfc04
death as if they exited via
Packit 7cfc04
.BR _exit (2)
Packit 7cfc04
with exit code 0.
Packit 7cfc04
.IP *
Packit 7cfc04
The execing tracee changes its thread ID while it is in the
Packit 7cfc04
.BR execve (2).
Packit 7cfc04
(Remember, under ptrace, the "pid" returned from
Packit 7cfc04
.BR waitpid (2),
Packit 7cfc04
or fed into ptrace calls, is the tracee's thread ID.)
Packit 7cfc04
That is, the tracee's thread ID is reset to be the same as its process ID,
Packit 7cfc04
which is the same as the thread group leader's thread ID.
Packit 7cfc04
.IP *
Packit 7cfc04
Then a
Packit 7cfc04
.B PTRACE_EVENT_EXEC
Packit 7cfc04
stop happens, if the
Packit 7cfc04
.BR PTRACE_O_TRACEEXEC
Packit 7cfc04
option was turned on.
Packit 7cfc04
.IP *
Packit 7cfc04
If the thread group leader has reported its
Packit 7cfc04
.B PTRACE_EVENT_EXIT
Packit 7cfc04
stop by this time,
Packit 7cfc04
it appears to the tracer that
Packit 7cfc04
the dead thread leader "reappears from nowhere".
Packit 7cfc04
(Note: the thread group leader does not report death via
Packit 7cfc04
.I WIFEXITED(status)
Packit 7cfc04
until there is at least one other live thread.
Packit 7cfc04
This eliminates the possibility that the tracer will see
Packit 7cfc04
it dying and then reappearing.)
Packit 7cfc04
If the thread group leader was still alive,
Packit 7cfc04
for the tracer this may look as if thread group leader
Packit 7cfc04
returns from a different system call than it entered,
Packit 7cfc04
or even "returned from a system call even though
Packit 7cfc04
it was not in any system call".
Packit 7cfc04
If the thread group leader was not traced
Packit 7cfc04
(or was traced by a different tracer), then during
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
it will appear as if it has become a tracee of
Packit 7cfc04
the tracer of the execing tracee.
Packit 7cfc04
.PP
Packit 7cfc04
All of the above effects are the artifacts of
Packit 7cfc04
the thread ID change in the tracee.
Packit 7cfc04
.PP
Packit 7cfc04
The
Packit 7cfc04
.B PTRACE_O_TRACEEXEC
Packit 7cfc04
option is the recommended tool for dealing with this situation.
Packit 7cfc04
First, it enables
Packit 7cfc04
.BR PTRACE_EVENT_EXEC
Packit 7cfc04
stop,
Packit 7cfc04
which occurs before
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
returns.
Packit 7cfc04
In this stop, the tracer can use
Packit 7cfc04
.B PTRACE_GETEVENTMSG
Packit 7cfc04
to retrieve the tracee's former thread ID.
Packit 7cfc04
(This feature was introduced in Linux 3.0.)
Packit 7cfc04
Second, the
Packit 7cfc04
.B PTRACE_O_TRACEEXEC
Packit 7cfc04
option disables legacy
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
generation on
Packit 7cfc04
.BR execve (2).
Packit 7cfc04
.PP
Packit 7cfc04
When the tracer receives
Packit 7cfc04
.B PTRACE_EVENT_EXEC
Packit 7cfc04
stop notification,
Packit 7cfc04
it is guaranteed that except this tracee and the thread group leader,
Packit 7cfc04
no other threads from the process are alive.
Packit 7cfc04
.PP
Packit 7cfc04
On receiving the
Packit 7cfc04
.B PTRACE_EVENT_EXEC
Packit 7cfc04
stop notification,
Packit 7cfc04
the tracer should clean up all its internal
Packit 7cfc04
data structures describing the threads of this process,
Packit 7cfc04
and retain only one data structure\(emone which
Packit 7cfc04
describes the single still running tracee, with
Packit 7cfc04
.PP
Packit 7cfc04
    thread ID == thread group ID == process ID.
Packit 7cfc04
.PP
Packit 7cfc04
Example: two threads call
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
at the same time:
Packit 7cfc04
.PP
Packit 7cfc04
.nf
Packit 7cfc04
*** we get syscall-enter-stop in thread 1: **
Packit 7cfc04
PID1 execve("/bin/foo", "foo" <unfinished ...>
Packit 7cfc04
*** we issue PTRACE_SYSCALL for thread 1 **
Packit 7cfc04
*** we get syscall-enter-stop in thread 2: **
Packit 7cfc04
PID2 execve("/bin/bar", "bar" <unfinished ...>
Packit 7cfc04
*** we issue PTRACE_SYSCALL for thread 2 **
Packit 7cfc04
*** we get PTRACE_EVENT_EXEC for PID0, we issue PTRACE_SYSCALL **
Packit 7cfc04
*** we get syscall-exit-stop for PID0: **
Packit 7cfc04
PID0 <... execve resumed> )             = 0
Packit 7cfc04
.fi
Packit 7cfc04
.PP
Packit 7cfc04
If the
Packit 7cfc04
.B PTRACE_O_TRACEEXEC
Packit 7cfc04
option is
Packit 7cfc04
.I not
Packit 7cfc04
in effect for the execing tracee,
Packit 7cfc04
and if the tracee was
Packit 7cfc04
.BR PTRACE_ATTACH ed
Packit 7cfc04
rather that
Packit 7cfc04
.BR PTRACE_SEIZE d,
Packit 7cfc04
the kernel delivers an extra
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
to the tracee after
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
returns.
Packit 7cfc04
This is an ordinary signal (similar to one which can be
Packit 7cfc04
generated by
Packit 7cfc04
.IR "kill -TRAP" ),
Packit 7cfc04
not a special kind of ptrace-stop.
Packit 7cfc04
Employing
Packit 7cfc04
.B PTRACE_GETSIGINFO
Packit 7cfc04
for this signal returns
Packit 7cfc04
.I si_code
Packit 7cfc04
set to 0
Packit 7cfc04
.RI ( SI_USER ).
Packit 7cfc04
This signal may be blocked by signal mask,
Packit 7cfc04
and thus may be delivered (much) later.
Packit 7cfc04
.PP
Packit 7cfc04
Usually, the tracer (for example,
Packit 7cfc04
.BR strace (1))
Packit 7cfc04
would not want to show this extra post-execve
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
signal to the user, and would suppress its delivery to the tracee (if
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
is set to
Packit 7cfc04
.BR SIG_DFL ,
Packit 7cfc04
it is a killing signal).
Packit 7cfc04
However, determining
Packit 7cfc04
.I which
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
to suppress is not easy.
Packit 7cfc04
Setting the
Packit 7cfc04
.B PTRACE_O_TRACEEXEC
Packit 7cfc04
option or using
Packit 7cfc04
.B PTRACE_SEIZE
Packit 7cfc04
and thus suppressing this extra
Packit 7cfc04
.B SIGTRAP
Packit 7cfc04
is the recommended approach.
Packit 7cfc04
.SS Real parent
Packit 7cfc04
The ptrace API (ab)uses the standard UNIX parent/child signaling over
Packit 7cfc04
.BR waitpid (2).
Packit 7cfc04
This used to cause the real parent of the process to stop receiving
Packit 7cfc04
several kinds of
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
notifications when the child process is traced by some other process.
Packit 7cfc04
.PP
Packit 7cfc04
Many of these bugs have been fixed, but as of Linux 2.6.38 several still
Packit 7cfc04
exist; see BUGS below.
Packit 7cfc04
.PP
Packit 7cfc04
As of Linux 2.6.38, the following is believed to work correctly:
Packit 7cfc04
.IP * 3
Packit 7cfc04
exit/death by signal is reported first to the tracer, then,
Packit 7cfc04
when the tracer consumes the
Packit 7cfc04
.BR waitpid (2)
Packit 7cfc04
result, to the real parent (to the real parent only when the
Packit 7cfc04
whole multithreaded process exits).
Packit 7cfc04
If the tracer and the real parent are the same process,
Packit 7cfc04
the report is sent only once.
Packit 7cfc04
.SH RETURN VALUE
Packit 7cfc04
On success, the
Packit 7cfc04
.B PTRACE_PEEK*
Packit 7cfc04
requests return the requested data (but see NOTES),
Packit 7cfc04
while other requests return zero.
Packit 7cfc04
.PP
Packit 7cfc04
On error, all requests return \-1, and
Packit 7cfc04
.I errno
Packit 7cfc04
is set appropriately.
Packit 7cfc04
Since the value returned by a successful
Packit 7cfc04
.B PTRACE_PEEK*
Packit 7cfc04
request may be \-1, the caller must clear
Packit 7cfc04
.I errno
Packit 7cfc04
before the call, and then check it afterward
Packit 7cfc04
to determine whether or not an error occurred.
Packit 7cfc04
.SH ERRORS
Packit 7cfc04
.TP
Packit 7cfc04
.B EBUSY
Packit 7cfc04
(i386 only) There was an error with allocating or freeing a debug register.
Packit 7cfc04
.TP
Packit 7cfc04
.B EFAULT
Packit 7cfc04
There was an attempt to read from or write to an invalid area in
Packit 7cfc04
the tracer's or the tracee's memory,
Packit 7cfc04
probably because the area wasn't mapped or accessible.
Packit 7cfc04
Unfortunately, under Linux, different variations of this fault
Packit 7cfc04
will return
Packit 7cfc04
.B EIO
Packit 7cfc04
or
Packit 7cfc04
.B EFAULT
Packit 7cfc04
more or less arbitrarily.
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
An attempt was made to set an invalid option.
Packit 7cfc04
.TP
Packit 7cfc04
.B EIO
Packit 7cfc04
.I request
Packit 7cfc04
is invalid, or an attempt was made to read from or
Packit 7cfc04
write to an invalid area in the tracer's or the tracee's memory,
Packit 7cfc04
or there was a word-alignment violation,
Packit 7cfc04
or an invalid signal was specified during a restart request.
Packit 7cfc04
.TP
Packit 7cfc04
.B EPERM
Packit 7cfc04
The specified process cannot be traced.
Packit 7cfc04
This could be because the
Packit 7cfc04
tracer has insufficient privileges (the required capability is
Packit 7cfc04
.BR CAP_SYS_PTRACE );
Packit 7cfc04
unprivileged processes cannot trace processes that they
Packit 7cfc04
cannot send signals to or those running
Packit 7cfc04
set-user-ID/set-group-ID programs, for obvious reasons.
Packit 7cfc04
Alternatively, the process may already be being traced,
Packit 7cfc04
or (on kernels before 2.6.26) be
Packit 7cfc04
.BR init (1)
Packit 7cfc04
(PID 1).
Packit 7cfc04
.TP
Packit 7cfc04
.B ESRCH
Packit 7cfc04
The specified process does not exist, or is not currently being traced
Packit 7cfc04
by the caller, or is not stopped
Packit 7cfc04
(for requests that require a stopped tracee).
Packit 7cfc04
.SH CONFORMING TO
Packit 7cfc04
SVr4, 4.3BSD.
Packit 7cfc04
.SH NOTES
Packit 7cfc04
Although arguments to
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
are interpreted according to the prototype given,
Packit 7cfc04
glibc currently declares
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
as a variadic function with only the
Packit 7cfc04
.I request
Packit 7cfc04
argument fixed.
Packit 7cfc04
It is recommended to always supply four arguments,
Packit 7cfc04
even if the requested operation does not use them,
Packit 7cfc04
setting unused/ignored arguments to
Packit 7cfc04
.I 0L
Packit 7cfc04
or
Packit 7cfc04
.IR "(void\ *)\ 0".
Packit 7cfc04
.PP
Packit 7cfc04
In Linux kernels before 2.6.26,
Packit 7cfc04
.\" See commit 00cd5c37afd5f431ac186dd131705048c0a11fdb
Packit 7cfc04
.BR init (1),
Packit 7cfc04
the process with PID 1, may not be traced.
Packit 7cfc04
.PP
Packit 7cfc04
A tracees parent continues to be the tracer even if that tracer calls
Packit 7cfc04
.BR execve (2).
Packit 7cfc04
.PP
Packit 7cfc04
The layout of the contents of memory and the USER area are
Packit 7cfc04
quite operating-system- and architecture-specific.
Packit 7cfc04
The offset supplied, and the data returned,
Packit 7cfc04
might not entirely match with the definition of
Packit 7cfc04
.IR "struct user" .
Packit 7cfc04
.\" See http://lkml.org/lkml/2008/5/8/375
Packit 7cfc04
.PP
Packit 7cfc04
The size of a "word" is determined by the operating-system variant
Packit 7cfc04
(e.g., for 32-bit Linux it is 32 bits).
Packit 7cfc04
.PP
Packit 7cfc04
This page documents the way the
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
call works currently in Linux.
Packit 7cfc04
Its behavior differs significantly on other flavors of UNIX.
Packit 7cfc04
In any case, use of
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
is highly specific to the operating system and architecture.
Packit 7cfc04
.\"
Packit 7cfc04
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Packit 7cfc04
.\"
Packit 7cfc04
.SS Ptrace access mode checking
Packit 7cfc04
Various parts of the kernel-user-space API (not just
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
operations), require so-called "ptrace access mode" checks,
Packit 7cfc04
whose outcome determines whether an operation is permitted
Packit 7cfc04
(or, in a few cases, causes a "read" operation to return sanitized data).
Packit 7cfc04
These checks are performed in cases where one process can
Packit 7cfc04
inspect sensitive information about,
Packit 7cfc04
or in some cases modify the state of, another process.
Packit 7cfc04
The checks are based on factors such as the credentials and capabilities
Packit 7cfc04
of the two processes,
Packit 7cfc04
whether or not the "target" process is dumpable,
Packit 7cfc04
and the results of checks performed by any enabled Linux Security Module
Packit 7cfc04
(LSM)\(emfor example, SELinux, Yama, or Smack\(emand by the commoncap LSM
Packit 7cfc04
(which is always invoked).
Packit 7cfc04
.PP
Packit 7cfc04
Prior to Linux 2.6.27, all access checks were of a single type.
Packit 7cfc04
Since Linux 2.6.27,
Packit 7cfc04
.\" commit 006ebb40d3d65338bd74abb03b945f8d60e362bd
Packit 7cfc04
two access mode levels are distinguished:
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_MODE_READ
Packit 7cfc04
For "read" operations or other operations that are less dangerous,
Packit 7cfc04
such as:
Packit 7cfc04
.BR get_robust_list (2);
Packit 7cfc04
.BR kcmp (2);
Packit 7cfc04
reading
Packit 7cfc04
.IR /proc/[pid]/auxv ,
Packit 7cfc04
.IR /proc/[pid]/environ ,
Packit 7cfc04
or
Packit 7cfc04
.IR /proc/[pid]/stat ;
Packit 7cfc04
or
Packit 7cfc04
.BR readlink (2)
Packit 7cfc04
of a
Packit 7cfc04
.IR /proc/[pid]/ns/*
Packit 7cfc04
file.
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_MODE_ATTACH
Packit 7cfc04
For "write" operations, or other operations that are more dangerous,
Packit 7cfc04
such as: ptrace attaching
Packit 7cfc04
.RB ( PTRACE_ATTACH )
Packit 7cfc04
to another process
Packit 7cfc04
or calling
Packit 7cfc04
.BR process_vm_writev (2).
Packit 7cfc04
.RB ( PTRACE_MODE_ATTACH
Packit 7cfc04
was effectively the default before Linux 2.6.27.)
Packit 7cfc04
.\"
Packit 7cfc04
.\" Regarding the above description of the distinction between
Packit 7cfc04
.\" PTRACE_MODE_READ and PTRACE_MODE_ATTACH, Stephen Smalley notes:
Packit 7cfc04
.\"
Packit 7cfc04
.\"     That was the intent when the distinction was introduced, but it doesn't
Packit 7cfc04
.\"     appear to have been properly maintained, e.g. there is now a common
Packit 7cfc04
.\"     helper lock_trace() that is used for
Packit 7cfc04
.\"     /proc/pid/{stack,syscall,personality} but checks PTRACE_MODE_ATTACH, and
Packit 7cfc04
.\"     PTRACE_MODE_ATTACH is also used in timerslack_ns_write/show().  Likely
Packit 7cfc04
.\"     should review and make them consistent.  There was also some debate
Packit 7cfc04
.\"     about proper handling of /proc/pid/fd.  Arguably that one might belong
Packit 7cfc04
.\"     back in the _ATTACH camp.
Packit 7cfc04
.\"
Packit 7cfc04
.PP
Packit 7cfc04
Since Linux 4.5,
Packit 7cfc04
.\" commit caaee6234d05a58c5b4d05e7bf766131b810a657
Packit 7cfc04
the above access mode checks are combined (ORed) with
Packit 7cfc04
one of the following modifiers:
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_MODE_FSCREDS
Packit 7cfc04
Use the caller's filesystem UID and GID (see
Packit 7cfc04
.BR credentials (7))
Packit 7cfc04
or effective capabilities for LSM checks.
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_MODE_REALCREDS
Packit 7cfc04
Use the caller's real UID and GID or permitted capabilities for LSM checks.
Packit 7cfc04
This was effectively the default before Linux 4.5.
Packit 7cfc04
.PP
Packit 7cfc04
Because combining one of the credential modifiers with one of
Packit 7cfc04
the aforementioned access modes is typical,
Packit 7cfc04
some macros are defined in the kernel sources for the combinations:
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_MODE_READ_FSCREDS
Packit 7cfc04
Defined as
Packit 7cfc04
.BR "PTRACE_MODE_READ | PTRACE_MODE_FSCREDS" .
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_MODE_READ_REALCREDS
Packit 7cfc04
Defined as
Packit 7cfc04
.BR "PTRACE_MODE_READ | PTRACE_MODE_REALCREDS" .
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_MODE_ATTACH_FSCREDS
Packit 7cfc04
Defined as
Packit 7cfc04
.BR "PTRACE_MODE_ATTACH | PTRACE_MODE_FSCREDS" .
Packit 7cfc04
.TP
Packit 7cfc04
.B PTRACE_MODE_ATTACH_REALCREDS
Packit 7cfc04
Defined as
Packit 7cfc04
.BR "PTRACE_MODE_ATTACH | PTRACE_MODE_REALCREDS" .
Packit 7cfc04
.PP
Packit 7cfc04
One further modifier can be ORed with the access mode:
Packit 7cfc04
.TP
Packit 7cfc04
.BR PTRACE_MODE_NOAUDIT " (since Linux 3.3)"
Packit 7cfc04
.\" commit 69f594a38967f4540ce7a29b3fd214e68a8330bd
Packit 7cfc04
.\" Just for /proc/pid/stat
Packit 7cfc04
Don't audit this access mode check.
Packit 7cfc04
This modifier is employed for ptrace access mode checks
Packit 7cfc04
(such as checks when reading
Packit 7cfc04
.IR /proc/[pid]/stat )
Packit 7cfc04
that merely cause the output to be filtered or sanitized,
Packit 7cfc04
rather than causing an error to be returned to the caller.
Packit 7cfc04
In these cases, accessing the file is not a security violation and
Packit 7cfc04
there is no reason to generate a security audit record.
Packit 7cfc04
This modifier suppresses the generation of
Packit 7cfc04
such an audit record for the particular access check.
Packit 7cfc04
.PP
Packit 7cfc04
Note that all of the
Packit 7cfc04
.BR PTRACE_MODE_*
Packit 7cfc04
constants described in this subsection are kernel-internal,
Packit 7cfc04
and not visible to user space.
Packit 7cfc04
The constant names are mentioned here in order to label the various kinds of
Packit 7cfc04
ptrace access mode checks that are performed for various system calls
Packit 7cfc04
and accesses to various pseudofiles (e.g., under
Packit 7cfc04
.IR /proc ).
Packit 7cfc04
These names are used in other manual pages to provide a simple
Packit 7cfc04
shorthand for labeling the different kernel checks.
Packit 7cfc04
.PP
Packit 7cfc04
The algorithm employed for ptrace access mode checking determines whether
Packit 7cfc04
the calling process is allowed to perform the corresponding action
Packit 7cfc04
on the target process.
Packit 7cfc04
(In the case of opening
Packit 7cfc04
.IR /proc/[pid]
Packit 7cfc04
files, the "calling process" is the one opening the file,
Packit 7cfc04
and the process with the corresponding PID is the "target process".)
Packit 7cfc04
The algorithm is as follows:
Packit 7cfc04
.IP 1. 3
Packit 7cfc04
If the calling thread and the target thread are in the same
Packit 7cfc04
thread group, access is always allowed.
Packit 7cfc04
.IP 2.
Packit 7cfc04
If the access mode specifies
Packit 7cfc04
.BR PTRACE_MODE_FSCREDS ,
Packit 7cfc04
then, for the check in the next step,
Packit 7cfc04
employ the caller's filesystem UID and GID.
Packit 7cfc04
(As noted in
Packit 7cfc04
.BR credentials (7),
Packit 7cfc04
the filesystem UID and GID almost always have the same values
Packit 7cfc04
as the corresponding effective IDs.)
Packit 7cfc04
.IP
Packit 7cfc04
Otherwise, the access mode specifies
Packit 7cfc04
.BR PTRACE_MODE_REALCREDS ,
Packit 7cfc04
so use the caller's real UID and GID for the checks in the next step.
Packit 7cfc04
(Most APIs that check the caller's UID and GID use the effective IDs.
Packit 7cfc04
For historical reasons, the
Packit 7cfc04
.BR PTRACE_MODE_REALCREDS
Packit 7cfc04
check uses the real IDs instead.)
Packit 7cfc04
.IP 3.
Packit 7cfc04
Deny access if
Packit 7cfc04
.I neither
Packit 7cfc04
of the following is true:
Packit 7cfc04
.RS
Packit 7cfc04
.IP \(bu 2
Packit 7cfc04
The real, effective, and saved-set user IDs of the target
Packit 7cfc04
match the caller's user ID,
Packit 7cfc04
.IR and
Packit 7cfc04
the real, effective, and saved-set group IDs of the target
Packit 7cfc04
match the caller's group ID.
Packit 7cfc04
.IP \(bu
Packit 7cfc04
The caller has the
Packit 7cfc04
.B CAP_SYS_PTRACE
Packit 7cfc04
capability in the user namespace of the target.
Packit 7cfc04
.RE
Packit 7cfc04
.IP 4.
Packit 7cfc04
Deny access if the target process "dumpable" attribute has a value other than 1
Packit 7cfc04
.RB ( SUID_DUMP_USER ;
Packit 7cfc04
see the discussion of
Packit 7cfc04
.BR PR_SET_DUMPABLE
Packit 7cfc04
in
Packit 7cfc04
.BR prctl (2)),
Packit 7cfc04
and the caller does not have the
Packit 7cfc04
.BR CAP_SYS_PTRACE
Packit 7cfc04
capability in the user namespace of the target process.
Packit 7cfc04
.IP 5.
Packit 7cfc04
The kernel LSM
Packit 7cfc04
.IR security_ptrace_access_check ()
Packit 7cfc04
interface is invoked to see if ptrace access is permitted.
Packit 7cfc04
The results depend on the LSM(s).
Packit 7cfc04
The implementation of this interface in the commoncap LSM performs
Packit 7cfc04
the following steps:
Packit 7cfc04
.\" (in cap_ptrace_access_check()):
Packit 7cfc04
.RS
Packit 7cfc04
.IP a) 3
Packit 7cfc04
If the access mode includes
Packit 7cfc04
.BR PTRACE_MODE_FSCREDS ,
Packit 7cfc04
then use the caller's
Packit 7cfc04
.I effective
Packit 7cfc04
capability set
Packit 7cfc04
in the following check;
Packit 7cfc04
otherwise (the access mode specifies
Packit 7cfc04
.BR PTRACE_MODE_REALCREDS ,
Packit 7cfc04
so) use the caller's
Packit 7cfc04
.I permitted
Packit 7cfc04
capability set.
Packit 7cfc04
.IP b)
Packit 7cfc04
Deny access if
Packit 7cfc04
.I neither
Packit 7cfc04
of the following is true:
Packit 7cfc04
.RS
Packit 7cfc04
.IP \(bu 2
Packit 7cfc04
The caller and the target process are in the same user namespace,
Packit 7cfc04
and the caller's capabilities are a proper superset of the target process's
Packit 7cfc04
.I permitted
Packit 7cfc04
capabilities.
Packit 7cfc04
.IP \(bu
Packit 7cfc04
The caller has the
Packit 7cfc04
.B CAP_SYS_PTRACE
Packit 7cfc04
capability in the target process's user namespace.
Packit 7cfc04
.RE
Packit 7cfc04
.IP
Packit 7cfc04
Note that the commoncap LSM does not distinguish between
Packit 7cfc04
.B PTRACE_MODE_READ
Packit 7cfc04
and
Packit 7cfc04
.BR PTRACE_MODE_ATTACH .
Packit 7cfc04
.RE
Packit 7cfc04
.IP 6.
Packit 7cfc04
If access has not been denied by any of the preceding steps,
Packit 7cfc04
then access is allowed.
Packit 7cfc04
.\"
Packit 7cfc04
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Packit 7cfc04
.\"
Packit 7cfc04
.SS /proc/sys/kernel/yama/ptrace_scope
Packit 7cfc04
On systems with the Yama Linux Security Module (LSM) installed
Packit 7cfc04
(i.e., the kernel was configured with
Packit 7cfc04
.BR CONFIG_SECURITY_YAMA ),
Packit 7cfc04
the
Packit 7cfc04
.I /proc/sys/kernel/yama/ptrace_scope
Packit 7cfc04
file (available since Linux 3.4)
Packit 7cfc04
.\" commit 2d514487faf188938a4ee4fb3464eeecfbdcf8eb
Packit 7cfc04
can be used to restrict the ability to trace a process with
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
(and thus also the ability to use tools such as
Packit 7cfc04
.BR strace (1)
Packit 7cfc04
and
Packit 7cfc04
.BR gdb (1)).
Packit 7cfc04
The goal of such restrictions is to prevent attack escalation whereby
Packit 7cfc04
a compromised process can ptrace-attach to other sensitive processes
Packit 7cfc04
(e.g., a GPG agent or an SSH session) owned by the user in order
Packit 7cfc04
to gain additional credentials that may exist in memory
Packit 7cfc04
and thus expand the scope of the attack.
Packit 7cfc04
.PP
Packit 7cfc04
More precisely, the Yama LSM limits two types of operations:
Packit 7cfc04
.IP * 3
Packit 7cfc04
Any operation that performs a ptrace access mode
Packit 7cfc04
.BR PTRACE_MODE_ATTACH
Packit 7cfc04
check\(emfor example,
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
.BR PTRACE_ATTACH .
Packit 7cfc04
(See the "Ptrace access mode checking" discussion above.)
Packit 7cfc04
.IP
Packit 7cfc04
.IP *
Packit 7cfc04
.BR ptrace ()
Packit 7cfc04
.BR PTRACE_TRACEME .
Packit 7cfc04
.PP
Packit 7cfc04
A process that has the
Packit 7cfc04
.B CAP_SYS_PTRACE
Packit 7cfc04
capability can update the
Packit 7cfc04
.IR /proc/sys/kernel/yama/ptrace_scope
Packit 7cfc04
file with one of the following values:
Packit 7cfc04
.TP
Packit 7cfc04
0 ("classic ptrace permissions")
Packit 7cfc04
No additional restrictions on operations that perform
Packit 7cfc04
.BR PTRACE_MODE_ATTACH
Packit 7cfc04
checks (beyond those imposed by the commoncap and other LSMs).
Packit 7cfc04
.IP
Packit 7cfc04
The use of
Packit 7cfc04
.BR PTRACE_TRACEME
Packit 7cfc04
is unchanged.
Packit 7cfc04
.TP
Packit 7cfc04
1 ("restricted ptrace") [default value]
Packit 7cfc04
When performing an operation that requires a
Packit 7cfc04
.BR PTRACE_MODE_ATTACH
Packit 7cfc04
check, the calling process must either have the
Packit 7cfc04
.B CAP_SYS_PTRACE
Packit 7cfc04
capability in the user namespace of the target process or
Packit 7cfc04
it must have a predefined relationship with the target process.
Packit 7cfc04
By default,
Packit 7cfc04
the predefined relationship is that the target process
Packit 7cfc04
must be a descendant of the caller.
Packit 7cfc04
.IP
Packit 7cfc04
A target process can employ the
Packit 7cfc04
.BR prctl (2)
Packit 7cfc04
.B PR_SET_PTRACER
Packit 7cfc04
operation to declare an additional PID that is allowed to perform
Packit 7cfc04
.BR PTRACE_MODE_ATTACH
Packit 7cfc04
operations on the target.
Packit 7cfc04
See the kernel source file
Packit 7cfc04
.IR Documentation/admin\-guide/LSM/Yama.rst
Packit 7cfc04
.\" commit 90bb766440f2147486a2acc3e793d7b8348b0c22
Packit 7cfc04
(or
Packit 7cfc04
.IR Documentation/security/Yama.txt
Packit 7cfc04
before Linux 4.13)
Packit 7cfc04
for further details.
Packit 7cfc04
.IP
Packit 7cfc04
The use of
Packit 7cfc04
.BR PTRACE_TRACEME
Packit 7cfc04
is unchanged.
Packit 7cfc04
.TP
Packit 7cfc04
2 ("admin-only attach")
Packit 7cfc04
Only processes with the
Packit 7cfc04
.B CAP_SYS_PTRACE
Packit 7cfc04
capability in the user namespace of the target process may perform
Packit 7cfc04
.BR PTRACE_MODE_ATTACH
Packit 7cfc04
operations or trace children that employ
Packit 7cfc04
.BR PTRACE_TRACEME .
Packit 7cfc04
.TP
Packit 7cfc04
3 ("no attach")
Packit 7cfc04
No process may perform
Packit 7cfc04
.BR PTRACE_MODE_ATTACH
Packit 7cfc04
operations or trace children that employ
Packit 7cfc04
.BR PTRACE_TRACEME .
Packit 7cfc04
.IP
Packit 7cfc04
Once this value has been written to the file, it cannot be changed.
Packit 7cfc04
.PP
Packit 7cfc04
With respect to values 1 and 2,
Packit 7cfc04
note that creating a new user namespace effectively removes the
Packit 7cfc04
protection offered by Yama.
Packit 7cfc04
This is because a process in the parent user namespace whose effective
Packit 7cfc04
UID matches the UID of the creator of a child namespace
Packit 7cfc04
has all capabilities (including
Packit 7cfc04
.BR CAP_SYS_PTRACE )
Packit 7cfc04
when performing operations within the child user namespace
Packit 7cfc04
(and further-removed descendants of that namespace).
Packit 7cfc04
Consequently, when a process tries to use user namespaces to sandbox itself,
Packit 7cfc04
it inadvertently weakens the protections offered by the Yama LSM.
Packit 7cfc04
.\"
Packit 7cfc04
.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Packit 7cfc04
.\"
Packit 7cfc04
.SS C library/kernel differences
Packit 7cfc04
At the system call level, the
Packit 7cfc04
.BR PTRACE_PEEKTEXT ,
Packit 7cfc04
.BR PTRACE_PEEKDATA ,
Packit 7cfc04
and
Packit 7cfc04
.BR PTRACE_PEEKUSER
Packit 7cfc04
requests have a different API: they store the result
Packit 7cfc04
at the address specified by the
Packit 7cfc04
.I data
Packit 7cfc04
parameter, and the return value is the error flag.
Packit 7cfc04
The glibc wrapper function provides the API given in DESCRIPTION above,
Packit 7cfc04
with the result being returned via the function return value.
Packit 7cfc04
.SH BUGS
Packit 7cfc04
On hosts with 2.6 kernel headers,
Packit 7cfc04
.B PTRACE_SETOPTIONS
Packit 7cfc04
is declared with a different value than the one for 2.4.
Packit 7cfc04
This leads to applications compiled with 2.6 kernel
Packit 7cfc04
headers failing when run on 2.4 kernels.
Packit 7cfc04
This can be worked around by redefining
Packit 7cfc04
.B PTRACE_SETOPTIONS
Packit 7cfc04
to
Packit 7cfc04
.BR PTRACE_OLDSETOPTIONS ,
Packit 7cfc04
if that is defined.
Packit 7cfc04
.PP
Packit 7cfc04
Group-stop notifications are sent to the tracer, but not to real parent.
Packit 7cfc04
Last confirmed on 2.6.38.6.
Packit 7cfc04
.PP
Packit 7cfc04
If a thread group leader is traced and exits by calling
Packit 7cfc04
.BR _exit (2),
Packit 7cfc04
.\" Note from Denys Vlasenko:
Packit 7cfc04
.\"     Here "exits" means any kind of death - _exit, exit_group,
Packit 7cfc04
.\"     signal death. Signal death and exit_group cases are trivial,
Packit 7cfc04
.\"     though: since signal death and exit_group kill all other threads
Packit 7cfc04
.\"     too, "until all other threads exit" thing happens rather soon
Packit 7cfc04
.\"     in these cases. Therefore, only _exit presents observably
Packit 7cfc04
.\"     puzzling behavior to ptrace users: thread leader _exit's,
Packit 7cfc04
.\"     but WIFEXITED isn't reported! We are trying to explain here
Packit 7cfc04
.\"     why it is so.
Packit 7cfc04
a
Packit 7cfc04
.B PTRACE_EVENT_EXIT
Packit 7cfc04
stop will happen for it (if requested), but the subsequent
Packit 7cfc04
.B WIFEXITED
Packit 7cfc04
notification will not be delivered until all other threads exit.
Packit 7cfc04
As explained above, if one of other threads calls
Packit 7cfc04
.BR execve (2),
Packit 7cfc04
the death of the thread group leader will
Packit 7cfc04
.I never
Packit 7cfc04
be reported.
Packit 7cfc04
If the execed thread is not traced by this tracer,
Packit 7cfc04
the tracer will never know that
Packit 7cfc04
.BR execve (2)
Packit 7cfc04
happened.
Packit 7cfc04
One possible workaround is to
Packit 7cfc04
.B PTRACE_DETACH
Packit 7cfc04
the thread group leader instead of restarting it in this case.
Packit 7cfc04
Last confirmed on 2.6.38.6.
Packit 7cfc04
.\"  FIXME . need to test/verify this scenario
Packit 7cfc04
.PP
Packit 7cfc04
A
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
signal may still cause a
Packit 7cfc04
.B PTRACE_EVENT_EXIT
Packit 7cfc04
stop before actual signal death.
Packit 7cfc04
This may be changed in the future;
Packit 7cfc04
.B SIGKILL
Packit 7cfc04
is meant to always immediately kill tasks even under ptrace.
Packit 7cfc04
Last confirmed on Linux 3.13.
Packit 7cfc04
.PP
Packit 7cfc04
Some system calls return with
Packit 7cfc04
.B EINTR
Packit 7cfc04
if a signal was sent to a tracee, but delivery was suppressed by the tracer.
Packit 7cfc04
(This is very typical operation: it is usually
Packit 7cfc04
done by debuggers on every attach, in order to not introduce
Packit 7cfc04
a bogus
Packit 7cfc04
.BR SIGSTOP ).
Packit 7cfc04
As of Linux 3.2.9, the following system calls are affected
Packit 7cfc04
(this list is likely incomplete):
Packit 7cfc04
.BR epoll_wait (2),
Packit 7cfc04
and
Packit 7cfc04
.BR read (2)
Packit 7cfc04
from an
Packit 7cfc04
.BR inotify (7)
Packit 7cfc04
file descriptor.
Packit 7cfc04
The usual symptom of this bug is that when you attach to
Packit 7cfc04
a quiescent process with the command
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
strace \-p <process-ID>
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
then, instead of the usual
Packit 7cfc04
and expected one-line output such as
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
restart_syscall(<... resuming interrupted call ...>_
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
or
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
select(6, [5], NULL, [5], NULL_
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
('_' denotes the cursor position), you observe more than one line.
Packit 7cfc04
For example:
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
    clock_gettime(CLOCK_MONOTONIC, {15370, 690928118}) = 0
Packit 7cfc04
    epoll_wait(4,_
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
What is not visible here is that the process was blocked in
Packit 7cfc04
.BR epoll_wait (2)
Packit 7cfc04
before
Packit 7cfc04
.BR strace (1)
Packit 7cfc04
has attached to it.
Packit 7cfc04
Attaching caused
Packit 7cfc04
.BR epoll_wait (2)
Packit 7cfc04
to return to user space with the error
Packit 7cfc04
.BR EINTR .
Packit 7cfc04
In this particular case, the program reacted to
Packit 7cfc04
.B EINTR
Packit 7cfc04
by checking the current time, and then executing
Packit 7cfc04
.BR epoll_wait (2)
Packit 7cfc04
again.
Packit 7cfc04
(Programs which do not expect such "stray"
Packit 7cfc04
.BR EINTR
Packit 7cfc04
errors may behave in an unintended way upon an
Packit 7cfc04
.BR strace (1)
Packit 7cfc04
attach.)
Packit 7cfc04
.SH SEE ALSO
Packit 7cfc04
.BR gdb (1),
Packit 7cfc04
.BR ltrace (1),
Packit 7cfc04
.BR strace (1),
Packit 7cfc04
.BR clone (2),
Packit 7cfc04
.BR execve (2),
Packit 7cfc04
.BR fork (2),
Packit 7cfc04
.BR gettid (2),
Packit 7cfc04
.BR prctl (2),
Packit 7cfc04
.BR seccomp (2),
Packit 7cfc04
.BR sigaction (2),
Packit 7cfc04
.BR tgkill (2),
Packit 7cfc04
.BR vfork (2),
Packit 7cfc04
.BR waitpid (2),
Packit 7cfc04
.BR exec (3),
Packit 7cfc04
.BR capabilities (7),
Packit 7cfc04
.BR signal (7)
Packit 7cfc04
.SH COLOPHON
Packit 7cfc04
This page is part of release 4.15 of the Linux
Packit 7cfc04
.I man-pages
Packit 7cfc04
project.
Packit 7cfc04
A description of the project,
Packit 7cfc04
information about reporting bugs,
Packit 7cfc04
and the latest version of this page,
Packit 7cfc04
can be found at
Packit 7cfc04
\%https://www.kernel.org/doc/man\-pages/.