44d040fe77
arguments. Reviewed by: jhb (previous version) Sponsored by: The FreeBSD Foundation MFC after: 3 weeks Differential revision: https://reviews.freebsd.org/D11080
1087 lines
27 KiB
Groff
1087 lines
27 KiB
Groff
.\" $FreeBSD$
|
|
.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
|
|
.\"
|
|
.\" This file is in the public domain.
|
|
.Dd June 11, 2017
|
|
.Dt PTRACE 2
|
|
.Os
|
|
.Sh NAME
|
|
.Nm ptrace
|
|
.Nd process tracing and debugging
|
|
.Sh LIBRARY
|
|
.Lb libc
|
|
.Sh SYNOPSIS
|
|
.In sys/types.h
|
|
.In sys/ptrace.h
|
|
.Ft int
|
|
.Fn ptrace "int request" "pid_t pid" "caddr_t addr" "int data"
|
|
.Sh DESCRIPTION
|
|
The
|
|
.Fn ptrace
|
|
system call
|
|
provides tracing and debugging facilities.
|
|
It allows one process
|
|
(the
|
|
.Em tracing
|
|
process)
|
|
to control another
|
|
(the
|
|
.Em traced
|
|
process).
|
|
The tracing process must first attach to the traced process, and then
|
|
issue a series of
|
|
.Fn ptrace
|
|
system calls to control the execution of the process, as well as access
|
|
process memory and register state.
|
|
For the duration of the tracing session, the traced process will be
|
|
.Dq re-parented ,
|
|
with its parent process ID (and resulting behavior)
|
|
changed to the tracing process.
|
|
It is permissible for a tracing process to attach to more than one
|
|
other process at a time.
|
|
When the tracing process has completed its work, it must detach the
|
|
traced process; if a tracing process exits without first detaching all
|
|
processes it has attached, those processes will be killed.
|
|
.Pp
|
|
Most of the time, the traced process runs normally, but when it
|
|
receives a signal
|
|
(see
|
|
.Xr sigaction 2 ) ,
|
|
it stops.
|
|
The tracing process is expected to notice this via
|
|
.Xr wait 2
|
|
or the delivery of a
|
|
.Dv SIGCHLD
|
|
signal, examine the state of the stopped process, and cause it to
|
|
terminate or continue as appropriate.
|
|
The signal may be a normal process signal, generated as a result of
|
|
traced process behavior, or use of the
|
|
.Xr kill 2
|
|
system call; alternatively, it may be generated by the tracing facility
|
|
as a result of attaching, stepping by the tracing
|
|
process,
|
|
or an event in the traced process.
|
|
The tracing process may choose to intercept the signal, using it to
|
|
observe process behavior (such as
|
|
.Dv SIGTRAP ) ,
|
|
or forward the signal to the process if appropriate.
|
|
The
|
|
.Fn ptrace
|
|
system call
|
|
is the mechanism by which all this happens.
|
|
.Pp
|
|
A traced process may report additional signal stops corresponding to
|
|
events in the traced process.
|
|
These additional signal stops are reported as
|
|
.Dv SIGTRAP
|
|
or
|
|
.Dv SIGSTOP
|
|
signals.
|
|
The tracing process can use the
|
|
.Dv PT_LWPINFO
|
|
request to determine which events are associated with a
|
|
.Dv SIGTRAP
|
|
or
|
|
.Dv SIGSTOP
|
|
signal.
|
|
Note that multiple events may be associated with a single signal.
|
|
For example, events indicated by the
|
|
.Dv PL_FLAG_BORN ,
|
|
.Dv PL_FLAG_FORKED ,
|
|
and
|
|
.Dv PL_FLAG_EXEC
|
|
flags are also reported as a system call exit event
|
|
.Pq Dv PL_FLAG_SCX .
|
|
The signal stop for a new child process enabled via
|
|
.Dv PTRACE_FORK
|
|
will report a
|
|
.Dv SIGSTOP
|
|
signal.
|
|
All other additional signal stops use
|
|
.Dv SIGTRAP .
|
|
.Pp
|
|
Each traced process has a tracing event mask.
|
|
An event in the traced process only reports a
|
|
signal stop if the corresponding flag is set in the tracing event mask.
|
|
The current set of tracing event flags include:
|
|
.Bl -tag -width "Dv PTRACE_SYSCALL"
|
|
.It Dv PTRACE_EXEC
|
|
Report a stop for a successful invocation of
|
|
.Xr execve 2 .
|
|
This event is indicated by the
|
|
.Dv PL_FLAG_EXEC
|
|
flag in the
|
|
.Va pl_flags
|
|
member of
|
|
.Vt "struct ptrace_lwpinfo" .
|
|
.It Dv PTRACE_SCE
|
|
Report a stop on each system call entry.
|
|
This event is indicated by the
|
|
.Dv PL_FLAG_SCE
|
|
flag in the
|
|
.Va pl_flags
|
|
member of
|
|
.Vt "struct ptrace_lwpinfo" .
|
|
.It Dv PTRACE_SCX
|
|
Report a stop on each system call exit.
|
|
This event is indicated by the
|
|
.Dv PL_FLAG_SCX
|
|
flag in the
|
|
.Va pl_flags
|
|
member of
|
|
.Vt "struct ptrace_lwpinfo" .
|
|
.It Dv PTRACE_SYSCALL
|
|
Report stops for both system call entry and exit.
|
|
.It Dv PTRACE_FORK
|
|
This event flag controls tracing for new child processes of a traced process.
|
|
.Pp
|
|
When this event flag is enabled,
|
|
new child processes will enable tracing and stop before executing their
|
|
first instruction.
|
|
The new child process will include the
|
|
.Dv PL_FLAG_CHILD
|
|
flag in the
|
|
.Va pl_flags
|
|
member of
|
|
.Vt "struct ptrace_lwpinfo" .
|
|
The traced process will report a stop that includes the
|
|
.Dv PL_FLAG_FORKED
|
|
flag.
|
|
The process ID of the new child process will also be present in the
|
|
.Va pl_child_pid
|
|
member of
|
|
.Vt "struct ptrace_lwpinfo" .
|
|
If the new child process was created via
|
|
.Xr vfork 2 ,
|
|
the traced process's stop will also include the
|
|
.Dv PL_FLAG_VFORKED
|
|
flag.
|
|
Note that new child processes will be attached with the default
|
|
tracing event mask;
|
|
they do not inherit the event mask of the traced process.
|
|
.Pp
|
|
When this event flag is not enabled,
|
|
new child processes will execute without tracing enabled.
|
|
.It Dv PTRACE_LWP
|
|
This event flag controls tracing of LWP
|
|
.Pq kernel thread
|
|
creation and destruction.
|
|
When this event is enabled,
|
|
new LWPs will stop and report an event with
|
|
.Dv PL_FLAG_BORN
|
|
set before executing their first instruction,
|
|
and exiting LWPs will stop and report an event with
|
|
.Dv PL_FLAG_EXITED
|
|
set before completing their termination.
|
|
.Pp
|
|
Note that new processes do not report an event for the creation of their
|
|
initial thread,
|
|
and exiting processes do not report an event for the termination of the
|
|
last thread.
|
|
.It Dv PTRACE_VFORK
|
|
Report a stop event when a parent process resumes after a
|
|
.Xr vfork 2 .
|
|
.Pp
|
|
When a thread in the traced process creates a new child process via
|
|
.Xr vfork 2 ,
|
|
the stop that reports
|
|
.Dv PL_FLAG_FORKED
|
|
and
|
|
.Dv PL_FLAG_SCX
|
|
occurs just after the child process is created,
|
|
but before the thread waits for the child process to stop sharing process
|
|
memory.
|
|
If a debugger is not tracing the new child process,
|
|
it must ensure that no breakpoints are enabled in the shared process
|
|
memory before detaching from the new child process.
|
|
This means that no breakpoints are enabled in the parent process either.
|
|
.Pp
|
|
The
|
|
.Dv PTRACE_VFORK
|
|
flag enables a new stop that indicates when the new child process stops
|
|
sharing the process memory of the parent process.
|
|
A debugger can reinsert breakpoints in the parent process and resume it
|
|
in response to this event.
|
|
This event is indicated by setting the
|
|
.Dv PL_FLAG_VFORK_DONE
|
|
flag.
|
|
.El
|
|
.Pp
|
|
The default tracing event mask when attaching to a process via
|
|
.Dv PT_ATTACH ,
|
|
.Dv PT_TRACE_ME ,
|
|
or
|
|
.Dv PTRACE_FORK
|
|
includes only
|
|
.Dv PTRACE_EXEC
|
|
events.
|
|
All other event flags are disabled.
|
|
.Pp
|
|
The
|
|
.Fa request
|
|
argument specifies what operation is being performed; the meaning of
|
|
the rest of the arguments depends on the operation, but except for one
|
|
special case noted below, all
|
|
.Fn ptrace
|
|
calls are made by the tracing process, and the
|
|
.Fa pid
|
|
argument specifies the process ID of the traced process
|
|
or a corresponding thread ID.
|
|
The
|
|
.Fa request
|
|
argument
|
|
can be:
|
|
.Bl -tag -width "Dv PT_GET_EVENT_MASK"
|
|
.It Dv PT_TRACE_ME
|
|
This request is the only one used by the traced process; it declares
|
|
that the process expects to be traced by its parent.
|
|
All the other arguments are ignored.
|
|
(If the parent process does not expect to trace the child, it will
|
|
probably be rather confused by the results; once the traced process
|
|
stops, it cannot be made to continue except via
|
|
.Fn ptrace . )
|
|
When a process has used this request and calls
|
|
.Xr execve 2
|
|
or any of the routines built on it
|
|
(such as
|
|
.Xr execv 3 ) ,
|
|
it will stop before executing the first instruction of the new image.
|
|
Also, any setuid or setgid bits on the executable being executed will
|
|
be ignored.
|
|
If the child was created by
|
|
.Xr vfork 2
|
|
system call or
|
|
.Xr rfork 2
|
|
call with the
|
|
.Dv RFMEM
|
|
flag specified, the debugging events are reported to the parent
|
|
only after the
|
|
.Xr execve 2
|
|
is executed.
|
|
.It Dv PT_READ_I , Dv PT_READ_D
|
|
These requests read a single
|
|
.Vt int
|
|
of data from the traced process's address space.
|
|
Traditionally,
|
|
.Fn ptrace
|
|
has allowed for machines with distinct address spaces for instruction
|
|
and data, which is why there are two requests: conceptually,
|
|
.Dv PT_READ_I
|
|
reads from the instruction space and
|
|
.Dv PT_READ_D
|
|
reads from the data space.
|
|
In the current
|
|
.Fx
|
|
implementation, these two requests are completely identical.
|
|
The
|
|
.Fa addr
|
|
argument specifies the address
|
|
(in the traced process's virtual address space)
|
|
at which the read is to be done.
|
|
This address does not have to meet any alignment constraints.
|
|
The value read is returned as the return value from
|
|
.Fn ptrace .
|
|
.It Dv PT_WRITE_I , Dv PT_WRITE_D
|
|
These requests parallel
|
|
.Dv PT_READ_I
|
|
and
|
|
.Dv PT_READ_D ,
|
|
except that they write rather than read.
|
|
The
|
|
.Fa data
|
|
argument supplies the value to be written.
|
|
.It Dv PT_IO
|
|
This request allows reading and writing arbitrary amounts of data in
|
|
the traced process's address space.
|
|
The
|
|
.Fa addr
|
|
argument specifies a pointer to a
|
|
.Vt "struct ptrace_io_desc" ,
|
|
which is defined as follows:
|
|
.Bd -literal
|
|
struct ptrace_io_desc {
|
|
int piod_op; /* I/O operation */
|
|
void *piod_offs; /* child offset */
|
|
void *piod_addr; /* parent offset */
|
|
size_t piod_len; /* request length */
|
|
};
|
|
|
|
/*
|
|
* Operations in piod_op.
|
|
*/
|
|
#define PIOD_READ_D 1 /* Read from D space */
|
|
#define PIOD_WRITE_D 2 /* Write to D space */
|
|
#define PIOD_READ_I 3 /* Read from I space */
|
|
#define PIOD_WRITE_I 4 /* Write to I space */
|
|
.Ed
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is ignored.
|
|
The actual number of bytes read or written is stored in
|
|
.Va piod_len
|
|
upon return.
|
|
.It Dv PT_CONTINUE
|
|
The traced process continues execution.
|
|
The
|
|
.Fa addr
|
|
argument
|
|
is an address specifying the place where execution is to be resumed
|
|
(a new value for the program counter),
|
|
or
|
|
.Po Vt caddr_t Pc Ns 1
|
|
to indicate that execution is to pick up where it left off.
|
|
The
|
|
.Fa data
|
|
argument
|
|
provides a signal number to be delivered to the traced process as it
|
|
resumes execution, or 0 if no signal is to be sent.
|
|
.It Dv PT_STEP
|
|
The traced process is single stepped one instruction.
|
|
The
|
|
.Fa addr
|
|
argument
|
|
should be passed
|
|
.Po Vt caddr_t Pc Ns 1 .
|
|
The
|
|
.Fa data
|
|
argument
|
|
provides a signal number to be delivered to the traced process as it
|
|
resumes execution, or 0 if no signal is to be sent.
|
|
.It Dv PT_KILL
|
|
The traced process terminates, as if
|
|
.Dv PT_CONTINUE
|
|
had been used with
|
|
.Dv SIGKILL
|
|
given as the signal to be delivered.
|
|
.It Dv PT_ATTACH
|
|
This request allows a process to gain control of an otherwise
|
|
unrelated process and begin tracing it.
|
|
It does not need any cooperation from the to-be-traced process.
|
|
In
|
|
this case,
|
|
.Fa pid
|
|
specifies the process ID of the to-be-traced process, and the other
|
|
two arguments are ignored.
|
|
This request requires that the target process must have the same real
|
|
UID as the tracing process, and that it must not be executing a setuid
|
|
or setgid executable.
|
|
(If the tracing process is running as root, these restrictions do not
|
|
apply.)
|
|
The tracing process will see the newly-traced process stop and may
|
|
then control it as if it had been traced all along.
|
|
.It Dv PT_DETACH
|
|
This request is like PT_CONTINUE, except that it does not allow
|
|
specifying an alternate place to continue execution, and after it
|
|
succeeds, the traced process is no longer traced and continues
|
|
execution normally.
|
|
.It Dv PT_GETREGS
|
|
This request reads the traced process's machine registers into the
|
|
.Do
|
|
.Vt "struct reg"
|
|
.Dc
|
|
(defined in
|
|
.In machine/reg.h )
|
|
pointed to by
|
|
.Fa addr .
|
|
.It Dv PT_SETREGS
|
|
This request is the converse of
|
|
.Dv PT_GETREGS ;
|
|
it loads the traced process's machine registers from the
|
|
.Do
|
|
.Vt "struct reg"
|
|
.Dc
|
|
(defined in
|
|
.In machine/reg.h )
|
|
pointed to by
|
|
.Fa addr .
|
|
.It Dv PT_GETFPREGS
|
|
This request reads the traced process's floating-point registers into
|
|
the
|
|
.Do
|
|
.Vt "struct fpreg"
|
|
.Dc
|
|
(defined in
|
|
.In machine/reg.h )
|
|
pointed to by
|
|
.Fa addr .
|
|
.It Dv PT_SETFPREGS
|
|
This request is the converse of
|
|
.Dv PT_GETFPREGS ;
|
|
it loads the traced process's floating-point registers from the
|
|
.Do
|
|
.Vt "struct fpreg"
|
|
.Dc
|
|
(defined in
|
|
.In machine/reg.h )
|
|
pointed to by
|
|
.Fa addr .
|
|
.It Dv PT_GETDBREGS
|
|
This request reads the traced process's debug registers into
|
|
the
|
|
.Do
|
|
.Vt "struct dbreg"
|
|
.Dc
|
|
(defined in
|
|
.In machine/reg.h )
|
|
pointed to by
|
|
.Fa addr .
|
|
.It Dv PT_SETDBREGS
|
|
This request is the converse of
|
|
.Dv PT_GETDBREGS ;
|
|
it loads the traced process's debug registers from the
|
|
.Do
|
|
.Vt "struct dbreg"
|
|
.Dc
|
|
(defined in
|
|
.In machine/reg.h )
|
|
pointed to by
|
|
.Fa addr .
|
|
.It Dv PT_LWPINFO
|
|
This request can be used to obtain information about the kernel thread,
|
|
also known as light-weight process, that caused the traced process to stop.
|
|
The
|
|
.Fa addr
|
|
argument specifies a pointer to a
|
|
.Vt "struct ptrace_lwpinfo" ,
|
|
which is defined as follows:
|
|
.Bd -literal
|
|
struct ptrace_lwpinfo {
|
|
lwpid_t pl_lwpid;
|
|
int pl_event;
|
|
int pl_flags;
|
|
sigset_t pl_sigmask;
|
|
sigset_t pl_siglist;
|
|
siginfo_t pl_siginfo;
|
|
char pl_tdname[MAXCOMLEN + 1];
|
|
pid_t pl_child_pid;
|
|
u_int pl_syscall_code;
|
|
u_int pl_syscall_narg;
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is to be set to the size of the structure known to the caller.
|
|
This allows the structure to grow without affecting older programs.
|
|
.Pp
|
|
The fields in the
|
|
.Vt "struct ptrace_lwpinfo"
|
|
have the following meaning:
|
|
.Bl -tag -width indent -compact
|
|
.It Va pl_lwpid
|
|
LWP id of the thread
|
|
.It Va pl_event
|
|
Event that caused the stop.
|
|
Currently defined events are:
|
|
.Bl -tag -width "Dv PL_EVENT_SIGNAL" -compact
|
|
.It Dv PL_EVENT_NONE
|
|
No reason given
|
|
.It Dv PL_EVENT_SIGNAL
|
|
Thread stopped due to the pending signal
|
|
.El
|
|
.It Va pl_flags
|
|
Flags that specify additional details about observed stop.
|
|
Currently defined flags are:
|
|
.Bl -tag -width indent -compact
|
|
.It Dv PL_FLAG_SCE
|
|
The thread stopped due to system call entry, right after the kernel is entered.
|
|
The debugger may examine syscall arguments that are stored in memory and
|
|
registers according to the ABI of the current process, and modify them,
|
|
if needed.
|
|
.It Dv PL_FLAG_SCX
|
|
The thread is stopped immediately before syscall is returning to the usermode.
|
|
The debugger may examine system call return values in the ABI-defined registers
|
|
and/or memory.
|
|
.It Dv PL_FLAG_EXEC
|
|
When
|
|
.Dv PL_FLAG_SCX
|
|
is set, this flag may be additionally specified to inform that the
|
|
program being executed by debuggee process has been changed by successful
|
|
execution of a system call from the
|
|
.Fn execve 2
|
|
family.
|
|
.It Dv PL_FLAG_SI
|
|
Indicates that
|
|
.Va pl_siginfo
|
|
member of
|
|
.Vt "struct ptrace_lwpinfo"
|
|
contains valid information.
|
|
.It Dv PL_FLAG_FORKED
|
|
Indicates that the process is returning from a call to
|
|
.Fn fork 2
|
|
that created a new child process.
|
|
The process identifier of the new process is available in the
|
|
.Va pl_child_pid
|
|
member of
|
|
.Vt "struct ptrace_lwpinfo" .
|
|
.It Dv PL_FLAG_CHILD
|
|
The flag is set for first event reported from a new child which is
|
|
automatically attached when
|
|
.Dv PTRACE_FORK
|
|
is enabled.
|
|
.It Dv PL_FLAG_BORN
|
|
This flag is set for the first event reported from a new LWP when
|
|
.Dv PTRACE_LWP
|
|
is enabled.
|
|
It is reported along with
|
|
.Dv PL_FLAG_SCX .
|
|
.It Dv PL_FLAG_EXITED
|
|
This flag is set for the last event reported by an exiting LWP when
|
|
.Dv PTRACE_LWP
|
|
is enabled.
|
|
Note that this event is not reported when the last LWP in a process exits.
|
|
The termination of the last thread is reported via a normal process exit
|
|
event.
|
|
.It Dv PL_FLAG_VFORKED
|
|
Indicates that the thread is returning from a call to
|
|
.Xr vfork 2
|
|
that created a new child process.
|
|
This flag is set in addition to
|
|
.Dv PL_FLAG_FORKED .
|
|
.It Dv PL_FLAG_VFORK_DONE
|
|
Indicates that the thread has resumed after a child process created via
|
|
.Xr vfork 2
|
|
has stopped sharing its address space with the traced process.
|
|
.El
|
|
.It Va pl_sigmask
|
|
The current signal mask of the LWP
|
|
.It Va pl_siglist
|
|
The current pending set of signals for the LWP.
|
|
Note that signals that are delivered to the process would not appear
|
|
on an LWP siglist until the thread is selected for delivery.
|
|
.It Va pl_siginfo
|
|
The siginfo that accompanies the signal pending.
|
|
Only valid for
|
|
.Dv PL_EVENT_SIGNAL
|
|
stop when
|
|
.Dv PL_FLAG_SI
|
|
is set in
|
|
.Va pl_flags .
|
|
.It Va pl_tdname
|
|
The name of the thread.
|
|
.It Va pl_child_pid
|
|
The process identifier of the new child process.
|
|
Only valid for a
|
|
.Dv PL_EVENT_SIGNAL
|
|
stop when
|
|
.Dv PL_FLAG_FORKED
|
|
is set in
|
|
.Va pl_flags .
|
|
.It Va pl_syscall_code
|
|
The ABI-specific identifier of the current system call.
|
|
Note that for indirect system calls this field reports the indirected
|
|
system call.
|
|
Only valid when
|
|
.Dv PL_FLAG_SCE
|
|
or
|
|
.Dv PL_FLAG_SCX
|
|
is set in
|
|
.Va pl_flags.
|
|
.It Va pl_syscall_narg
|
|
The number of arguments passed to the current system call not counting
|
|
the system call identifier.
|
|
Note that for indirect system calls this field reports the arguments
|
|
passed to the indirected system call.
|
|
Only valid when
|
|
.Dv PL_FLAG_SCE
|
|
or
|
|
.Dv PL_FLAG_SCX
|
|
is set in
|
|
.Va pl_flags.
|
|
.El
|
|
.It Dv PT_GETNUMLWPS
|
|
This request returns the number of kernel threads associated with the
|
|
traced process.
|
|
.It Dv PT_GETLWPLIST
|
|
This request can be used to get the current thread list.
|
|
A pointer to an array of type
|
|
.Vt lwpid_t
|
|
should be passed in
|
|
.Fa addr ,
|
|
with the array size specified by
|
|
.Fa data .
|
|
The return value from
|
|
.Fn ptrace
|
|
is the count of array entries filled in.
|
|
.It Dv PT_SETSTEP
|
|
This request will turn on single stepping of the specified process.
|
|
.It Dv PT_CLEARSTEP
|
|
This request will turn off single stepping of the specified process.
|
|
.It Dv PT_SUSPEND
|
|
This request will suspend the specified thread.
|
|
.It Dv PT_RESUME
|
|
This request will resume the specified thread.
|
|
.It Dv PT_TO_SCE
|
|
This request will set the
|
|
.Dv PTRACE_SCE
|
|
event flag to trace all future system call entries and continue the process.
|
|
The
|
|
.Fa addr
|
|
and
|
|
.Fa data
|
|
arguments are used the same as for
|
|
.Dv PT_CONTINUE.
|
|
.It Dv PT_TO_SCX
|
|
This request will set the
|
|
.Dv PTRACE_SCX
|
|
event flag to trace all future system call exits and continue the process.
|
|
The
|
|
.Fa addr
|
|
and
|
|
.Fa data
|
|
arguments are used the same as for
|
|
.Dv PT_CONTINUE.
|
|
.It Dv PT_SYSCALL
|
|
This request will set the
|
|
.Dv PTRACE_SYSCALL
|
|
event flag to trace all future system call entries and exits and continue
|
|
the process.
|
|
The
|
|
.Fa addr
|
|
and
|
|
.Fa data
|
|
arguments are used the same as for
|
|
.Dv PT_CONTINUE.
|
|
.It Dv PT_GET_SC_ARGS
|
|
For the thread which is stopped in either
|
|
.Dv PL_FLAG_SCE
|
|
or
|
|
.Dv PL_FLAG_SCX
|
|
state, that is, on entry or exit to a syscall,
|
|
this request fetches the syscall arguments.
|
|
.Pp
|
|
The arguments are copied out into the buffer pointed to by the
|
|
.Fa addr
|
|
pointer, sequentially.
|
|
Each syscall argument is stored as the machine word.
|
|
Kernel copies out as many arguments as the syscall accepts,
|
|
see the
|
|
.Va pl_syscall_narg
|
|
member of the
|
|
.Vt struct ptrace_lwpinfo ,
|
|
but not more than the
|
|
.Fa data
|
|
bytes in total are copied.
|
|
.It Dv PT_FOLLOW_FORK
|
|
This request controls tracing for new child processes of a traced process.
|
|
If
|
|
.Fa data
|
|
is non-zero,
|
|
.Dv PTRACE_FORK
|
|
is set in the traced process's event tracing mask.
|
|
If
|
|
.Fa data
|
|
is zero,
|
|
.Dv PTRACE_FORK
|
|
is cleared from the traced process's event tracing mask.
|
|
.It Dv PT_LWP_EVENTS
|
|
This request controls tracing of LWP creation and destruction.
|
|
If
|
|
.Fa data
|
|
is non-zero,
|
|
.Dv PTRACE_LWP
|
|
is set in the traced process's event tracing mask.
|
|
If
|
|
.Fa data
|
|
is zero,
|
|
.Dv PTRACE_LWP
|
|
is cleared from the traced process's event tracing mask.
|
|
.It Dv PT_GET_EVENT_MASK
|
|
This request reads the traced process's event tracing mask into the
|
|
integer pointed to by
|
|
.Fa addr .
|
|
The size of the integer must be passed in
|
|
.Fa data .
|
|
.It Dv PT_SET_EVENT_MASK
|
|
This request sets the traced process's event tracing mask from the
|
|
integer pointed to by
|
|
.Fa addr .
|
|
The size of the integer must be passed in
|
|
.Fa data .
|
|
.It Dv PT_VM_TIMESTAMP
|
|
This request returns the generation number or timestamp of the memory map of
|
|
the traced process as the return value from
|
|
.Fn ptrace .
|
|
This provides a low-cost way for the tracing process to determine if the
|
|
VM map changed since the last time this request was made.
|
|
.It Dv PT_VM_ENTRY
|
|
This request is used to iterate over the entries of the VM map of the traced
|
|
process.
|
|
The
|
|
.Fa addr
|
|
argument specifies a pointer to a
|
|
.Vt "struct ptrace_vm_entry" ,
|
|
which is defined as follows:
|
|
.Bd -literal
|
|
struct ptrace_vm_entry {
|
|
int pve_entry;
|
|
int pve_timestamp;
|
|
u_long pve_start;
|
|
u_long pve_end;
|
|
u_long pve_offset;
|
|
u_int pve_prot;
|
|
u_int pve_pathlen;
|
|
long pve_fileid;
|
|
uint32_t pve_fsid;
|
|
char *pve_path;
|
|
};
|
|
.Ed
|
|
.Pp
|
|
The first entry is returned by setting
|
|
.Va pve_entry
|
|
to zero.
|
|
Subsequent entries are returned by leaving
|
|
.Va pve_entry
|
|
unmodified from the value returned by previous requests.
|
|
The
|
|
.Va pve_timestamp
|
|
field can be used to detect changes to the VM map while iterating over the
|
|
entries.
|
|
The tracing process can then take appropriate action, such as restarting.
|
|
By setting
|
|
.Va pve_pathlen
|
|
to a non-zero value on entry, the pathname of the backing object is returned
|
|
in the buffer pointed to by
|
|
.Va pve_path ,
|
|
provided the entry is backed by a vnode.
|
|
The
|
|
.Va pve_pathlen
|
|
field is updated with the actual length of the pathname (including the
|
|
terminating null character).
|
|
The
|
|
.Va pve_offset
|
|
field is the offset within the backing object at which the range starts.
|
|
The range is located in the VM space at
|
|
.Va pve_start
|
|
and extends up to
|
|
.Va pve_end
|
|
(inclusive).
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is ignored.
|
|
.El
|
|
.Sh x86 MACHINE-SPECIFIC REQUESTS
|
|
.Bl -tag -width "Dv PT_GETXSTATE_INFO"
|
|
.It Dv PT_GETXMMREGS
|
|
Copy the XMM FPU state into the buffer pointed to by the
|
|
argument
|
|
.Fa addr .
|
|
The buffer has the same layout as the 32-bit save buffer for the
|
|
machine instruction
|
|
.Dv FXSAVE .
|
|
.Pp
|
|
This request is only valid for i386 programs, both on native 32-bit
|
|
systems and on amd64 kernels.
|
|
For 64-bit amd64 programs, the XMM state is reported as part of
|
|
the FPU state returned by the
|
|
.Dv PT_GETFPREGS
|
|
request.
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is ignored.
|
|
.It Dv PT_SETXMMREGS
|
|
Load the XMM FPU state for the thread from the buffer pointed to
|
|
by the argument
|
|
.Fa addr .
|
|
The buffer has the same layout as the 32-bit load buffer for the
|
|
machine instruction
|
|
.Dv FXRSTOR .
|
|
.Pp
|
|
As with
|
|
.Dv PT_GETXMMREGS,
|
|
this request is only valid for i386 programs.
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is ignored.
|
|
.It Dv PT_GETXSTATE_INFO
|
|
Report which XSAVE FPU extensions are supported by the CPU
|
|
and allowed in userspace programs.
|
|
The
|
|
.Fa addr
|
|
argument must point to a variable of type
|
|
.Vt struct ptrace_xstate_info ,
|
|
which contains the information on the request return.
|
|
.Vt struct ptrace_xstate_info
|
|
is defined as follows:
|
|
.Bd -literal
|
|
struct ptrace_xstate_info {
|
|
uint64_t xsave_mask;
|
|
uint32_t xsave_len;
|
|
};
|
|
.Ed
|
|
The
|
|
.Dv xsave_mask
|
|
field is a bitmask of the currently enabled extensions.
|
|
The meaning of the bits is defined in the Intel and AMD
|
|
processor documentation.
|
|
The
|
|
.Dv xsave_len
|
|
field reports the length of the XSAVE area for storing the hardware
|
|
state for currently enabled extensions in the format defined by the x86
|
|
.Dv XSAVE
|
|
machine instruction.
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument value must be equal to the size of the
|
|
.Vt struct ptrace_xstate_info .
|
|
.It Dv PT_GETXSTATE
|
|
Return the content of the XSAVE area for the thread.
|
|
The
|
|
.Fa addr
|
|
argument points to the buffer where the content is copied, and the
|
|
.Fa data
|
|
argument specifies the size of the buffer.
|
|
The kernel copies out as much content as allowed by the buffer size.
|
|
The buffer layout is specified by the layout of the save area for the
|
|
.Dv XSAVE
|
|
machine instruction.
|
|
.It Dv PT_SETXSTATE
|
|
Load the XSAVE state for the thread from the buffer specified by the
|
|
.Fa addr
|
|
pointer.
|
|
The buffer size is passed in the
|
|
.Fa data
|
|
argument.
|
|
The buffer must be at least as large as the
|
|
.Vt struct savefpu
|
|
(defined in
|
|
.Pa x86/fpu.h )
|
|
to allow the complete x87 FPU and XMM state load.
|
|
It must not be larger than the XSAVE state length, as reported by the
|
|
.Dv xsave_len
|
|
field from the
|
|
.Vt struct ptrace_xstate_info
|
|
of the
|
|
.Dv PT_GETXSTATE_INFO
|
|
request.
|
|
Layout of the buffer is identical to the layout of the load area for the
|
|
.Dv XRSTOR
|
|
machine instruction.
|
|
.It Dv PT_GETFSBASE
|
|
Return the value of the base used when doing segmented
|
|
memory addressing using the %fs segment register.
|
|
The
|
|
.Fa addr
|
|
argument points to an
|
|
.Vt unsigned long
|
|
variable where the base value is stored.
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is ignored.
|
|
.It Dv PT_GETGSBASE
|
|
Like the
|
|
.Dv PT_GETFSBASE
|
|
request, but returns the base for the %gs segment register.
|
|
.It Dv PT_SETFSBASE
|
|
Set the base for the %fs segment register to the value pointed to
|
|
by the
|
|
.Fa addr
|
|
argument.
|
|
.Fa addr
|
|
must point to the
|
|
.Vt unsigned long
|
|
variable containing the new base.
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is ignored.
|
|
.It Dv PT_SETGSBASE
|
|
Like the
|
|
.Dv PT_SETFSBASE
|
|
request, but sets the base for the %gs segment register.
|
|
.El
|
|
.Sh PowerPC MACHINE-SPECIFIC REQUESTS
|
|
.Bl -tag -width "Dv PT_SETVRREGS"
|
|
.It Dv PT_GETVRREGS
|
|
Return the thread's
|
|
.Dv ALTIVEC
|
|
machine state in the buffer pointed to by
|
|
.Fa addr .
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is ignored.
|
|
.It Dv PT_SETVRREGS
|
|
Set the thread's
|
|
.Dv ALTIVEC
|
|
machine state from the buffer pointed to by
|
|
.Fa addr .
|
|
.Pp
|
|
The
|
|
.Fa data
|
|
argument is ignored.
|
|
.El
|
|
.Pp
|
|
Additionally, other machine-specific requests can exist.
|
|
.Sh RETURN VALUES
|
|
Most requests return 0 on success and \-1 on error.
|
|
Some requests can cause
|
|
.Fn ptrace
|
|
to return
|
|
\-1
|
|
as a non-error value, among them are
|
|
.Dv PT_READ_I
|
|
and
|
|
.Dv PT_READ_D ,
|
|
which return the value read from the process memory on success.
|
|
To disambiguate,
|
|
.Va errno
|
|
can be set to 0 before the call and checked afterwards.
|
|
.Pp
|
|
The current
|
|
.Fn ptrace
|
|
implementation always sets
|
|
.Va errno
|
|
to 0 before calling into the kernel, both for historic reasons and for
|
|
consistency with other operating systems.
|
|
It is recommended to assign zero to
|
|
.Va errno
|
|
explicitly for forward compatibility.
|
|
.Sh ERRORS
|
|
The
|
|
.Fn ptrace
|
|
system call may fail if:
|
|
.Bl -tag -width Er
|
|
.It Bq Er ESRCH
|
|
.Bl -bullet -compact
|
|
.It
|
|
No process having the specified process ID exists.
|
|
.El
|
|
.It Bq Er EINVAL
|
|
.Bl -bullet -compact
|
|
.It
|
|
A process attempted to use
|
|
.Dv PT_ATTACH
|
|
on itself.
|
|
.It
|
|
The
|
|
.Fa request
|
|
argument
|
|
was not one of the legal requests.
|
|
.It
|
|
The signal number
|
|
(in
|
|
.Fa data )
|
|
to
|
|
.Dv PT_CONTINUE
|
|
was neither 0 nor a legal signal number.
|
|
.It
|
|
.Dv PT_GETREGS ,
|
|
.Dv PT_SETREGS ,
|
|
.Dv PT_GETFPREGS ,
|
|
.Dv PT_SETFPREGS ,
|
|
.Dv PT_GETDBREGS ,
|
|
or
|
|
.Dv PT_SETDBREGS
|
|
was attempted on a process with no valid register set.
|
|
(This is normally true only of system processes.)
|
|
.It
|
|
.Dv PT_VM_ENTRY
|
|
was given an invalid value for
|
|
.Fa pve_entry .
|
|
This can also be caused by changes to the VM map of the process.
|
|
.It
|
|
The size (in
|
|
.Fa data )
|
|
provided to
|
|
.Dv PT_LWPINFO
|
|
was less than or equal to zero, or larger than the
|
|
.Vt ptrace_lwpinfo
|
|
structure known to the kernel.
|
|
.It
|
|
The size (in
|
|
.Fa data )
|
|
provided to the x86-specific
|
|
.Dv PT_GETXSTATE_INFO
|
|
request was not equal to the size of the
|
|
.Vt struct ptrace_xstate_info .
|
|
.It
|
|
The size (in
|
|
.Fa data )
|
|
provided to the x86-specific
|
|
.Dv PT_SETXSTATE
|
|
request was less than the size of the x87 plus the XMM save area.
|
|
.It
|
|
The size (in
|
|
.Fa data )
|
|
provided to the x86-specific
|
|
.Dv PT_SETXSTATE
|
|
request was larger than returned in the
|
|
.Dv xsave_len
|
|
member of the
|
|
.Vt struct ptrace_xstate_info
|
|
from the
|
|
.Dv PT_GETXSTATE_INFO
|
|
request.
|
|
.It
|
|
The base value, provided to the amd64-specific requests
|
|
.Dv PT_SETFSBASE
|
|
or
|
|
.Dv PT_SETGSBASE ,
|
|
pointed outside of the valid user address space.
|
|
This error will not occur in 32-bit programs.
|
|
.El
|
|
.It Bq Er EBUSY
|
|
.Bl -bullet -compact
|
|
.It
|
|
.Dv PT_ATTACH
|
|
was attempted on a process that was already being traced.
|
|
.It
|
|
A request attempted to manipulate a process that was being traced by
|
|
some process other than the one making the request.
|
|
.It
|
|
A request
|
|
(other than
|
|
.Dv PT_ATTACH )
|
|
specified a process that was not stopped.
|
|
.El
|
|
.It Bq Er EPERM
|
|
.Bl -bullet -compact
|
|
.It
|
|
A request
|
|
(other than
|
|
.Dv PT_ATTACH )
|
|
attempted to manipulate a process that was not being traced at all.
|
|
.It
|
|
An attempt was made to use
|
|
.Dv PT_ATTACH
|
|
on a process in violation of the requirements listed under
|
|
.Dv PT_ATTACH
|
|
above.
|
|
.El
|
|
.It Bq Er ENOENT
|
|
.Bl -bullet -compact
|
|
.It
|
|
.Dv PT_VM_ENTRY
|
|
previously returned the last entry of the memory map.
|
|
No more entries exist.
|
|
.El
|
|
.It Bq Er ENAMETOOLONG
|
|
.Bl -bullet -compact
|
|
.It
|
|
.Dv PT_VM_ENTRY
|
|
cannot return the pathname of the backing object because the buffer is not big
|
|
enough.
|
|
.Fa pve_pathlen
|
|
holds the minimum buffer size required on return.
|
|
.El
|
|
.El
|
|
.Sh SEE ALSO
|
|
.Xr execve 2 ,
|
|
.Xr sigaction 2 ,
|
|
.Xr wait 2 ,
|
|
.Xr execv 3 ,
|
|
.Xr i386_clr_watch 3 ,
|
|
.Xr i386_set_watch 3
|
|
.Sh HISTORY
|
|
The
|
|
.Fn ptrace
|
|
function appeared in
|
|
.At v7 .
|