xref: /openbsd/lib/libc/sys/ptrace.2 (revision d32639f6)
1.\"	$OpenBSD: ptrace.2,v 1.43 2022/09/11 06:38:11 jmc Exp $
2.\"	$NetBSD: ptrace.2,v 1.3 1996/02/23 01:39:41 jtc Exp $
3.\"
4.\" This file is in the public domain.
5.Dd $Mdocdate: September 11 2022 $
6.Dt PTRACE 2
7.Os
8.Sh NAME
9.Nm ptrace
10.Nd process tracing and debugging
11.Sh SYNOPSIS
12.In sys/types.h
13.In sys/ptrace.h
14.Ft int
15.Fn ptrace "int request" "pid_t pid" "caddr_t addr" "int data"
16.Sh DESCRIPTION
17.Fn ptrace
18provides tracing and debugging facilities.
19It allows one process (the
20.Em tracing
21process) to control another (the
22.Em traced
23process).
24Most of the time, the traced process runs normally, but when
25it receives a signal
26.Po
27see
28.Xr sigaction 2
29.Pc ,
30it stops.
31The tracing process is expected to notice this via
32.Xr wait 2
33or the delivery of a
34.Dv SIGCHLD
35signal, examine the state of the stopped process, and cause it to
36terminate or continue as appropriate.
37.Fn ptrace
38is the mechanism by which all this happens.
39.Fn ptrace
40is only available on kernels compiled with the
41.Cm PTRACE
42option.
43.Pp
44The
45.Fa request
46argument specifies what operation is being performed; the meaning of
47the rest of the arguments depends on the operation, but except for one
48special case noted below, all
49.Fn ptrace
50calls are made by the tracing process, and the
51.Fa pid
52argument specifies the process ID of the traced process.
53.Fa request
54can be:
55.Bl -tag -width 12n
56.It Dv PT_TRACE_ME
57This request is the only one used by the traced process; it declares
58that the process expects to be traced by its parent.
59All the other arguments are ignored.
60(If the parent process does not expect to trace the child, it will
61probably be rather confused by the results; once the traced process stops,
62it cannot be made to continue except via
63.Fn ptrace . )
64When a process has used this request and calls
65.Xr execve 2
66or any of the routines built on it
67.Po
68such as
69.Xr execv 3
70.Pc ,
71it will stop before executing the first instruction of the new image.
72Also, any setuid or setgid bits on the executable being executed will
73be ignored.
74.It Dv PT_READ_I , Dv PT_READ_D
75These requests read a single
76.Vt int
77of data from the traced process' address space.
78Traditionally,
79.Fn ptrace
80has allowed for machines with distinct address spaces for instruction
81and data, which is why there are two requests: conceptually,
82.Dv PT_READ_I
83reads from the instruction space and
84.Dv PT_READ_D
85reads from the data space.
86In the current
87.Ox
88implementation, these two requests operate in the same address space.
89The
90.Fa addr
91argument specifies the address (in the traced process' virtual address
92space) at which the read is to be done.
93This address does not have to meet any alignment constraints.
94The value read is returned as the return value from
95.Fn ptrace .
96.It Dv PT_WRITE_I , Dv PT_WRITE_D
97These requests parallel
98.Dv PT_READ_I
99and
100.Dv PT_READ_D ,
101except that they write rather than read.
102.Dv PT_WRITE_I
103may be necessary to ensure that instruction caches are flushed appropriately.
104The
105.Fa data
106argument supplies the value to be written.
107.\" .It Dv PT_READ_U
108.\" This request reads an
109.\" .Li int
110.\" from the traced process' user structure.
111.\" The
112.\" .Fa addr
113.\" argument specifies the location of the int relative to the base of the
114.\" user structure; it will usually be an integer value cast to
115.\" .Li caddr_t
116.\" either explicitly or via the presence of a prototype for
117.\" .Fn ptrace .
118.\" Unlike
119.\" .Dv PT_READ_I
120.\" and
121.\" .Dv PT_READ_D ,
122.\" .Fa addr
123.\" must be aligned on an
124.\" .Li int
125.\" boundary.
126.\" The value read is returned as the return value from
127.\" .Fn ptrace .
128.\" .It Dv PT_WRITE_U
129.\" This request writes an
130.\" .Li int
131.\" into the traced process' user structure.
132.\" .Fa addr
133.\" specifies the offset, just as for
134.\" .Dv PT_READ_U ,
135.\" and
136.\" .Fa data
137.\" specifies the value to be written, just as for
138.\" .Dv PT_WRITE_I
139.\" and
140.\" .Dv PT_WRITE_D .
141.It Dv PT_CONTINUE
142The traced process continues execution.
143.Fa addr
144is an address specifying the place where execution is to be resumed (a
145new value for the program counter), or
146.Li (caddr_t)1
147to indicate that execution is to pick up where it left off.
148.Fa data
149provides a signal number to be delivered to the traced process as it
150resumes execution, or 0 if no signal is to be sent.
151.It Dv PT_KILL
152The traced process terminates, as if
153.Dv PT_CONTINUE
154had been used with
155.Dv SIGKILL
156given as the signal to be delivered.
157.It Dv PT_ATTACH
158This request allows a process to gain control of an otherwise unrelated
159process and begin tracing it.
160It does not need any cooperation from the to-be-traced process.
161In this case,
162.Fa pid
163specifies the process ID of the to-be-traced process, and the other two
164arguments are ignored.
165This request requires that the target process must have the same real UID
166as the tracing process, and that it must not be executing a set-user-ID
167or set-group-ID executable.
168Additionally, if the
169.Dv kern.global_ptrace
170sysctl is 0, then the target process must be a descendant of the tracing
171process.
172(If the tracing process is running as root, these restrictions do not apply.)
173The tracing process will see the newly traced process stop and may then
174control it as if it had been traced all along.
175.It Dv PT_DETACH
176This request is like
177.Dv PT_CONTINUE ,
178except that it does not allow
179specifying an alternate place to continue execution, and after it
180succeeds, the traced process is no longer traced and continues
181execution normally.
182.It Dv PT_IO
183This request is a more general interface that can be used instead of
184.Dv PT_READ_D ,
185.Dv PT_WRITE_D ,
186.Dv PT_READ_I
187and
188.Dv PT_WRITE_I .
189The I/O request is encoded in a
190.Dq Li "struct ptrace_io_desc"
191defined as:
192.Bd -literal -offset indent
193struct ptrace_io_desc {
194	int	 piod_op;
195	void	*piod_offs;
196	void	*piod_addr;
197	size_t	 piod_len;
198};
199.Ed
200.Pp
201Where
202.Fa piod_offs
203is the offset within the traced process where the I/O operation should be
204made,
205.Fa piod_addr
206is the buffer in the parent and
207.Fa piod_len
208is the length of the I/O request.
209The
210.Fa piod_op
211member specifies what operation needs to be done.
212Possible values are:
213.Pp
214.Bl -tag -width Ds -offset indent -compact
215.It PIOD_READ_D
216.It PIOD_WRITE_D
217.It PIOD_READ_I
218.It PIOD_WRITE_I
219.It PIOD_READ_AUXV
220.El
221.Pp
222See also the description of
223.Dv PT_READ_I
224for the difference between D and I spaces.
225The
226.Dv PIOD_READ_AUXV
227operation can be used to read from the ELF auxiliary vector.
228A pointer to the descriptor is passed in
229.Fa addr .
230On return the
231.Fa piod_len
232field in the descriptor will be updated with the actual number of bytes
233transferred.
234If the requested I/O could not be successfully performed,
235.Fn ptrace
236will return
237.Li -1
238and set
239.Va errno .
240.It Dv PT_SET_EVENT_MASK
241This request can be used to specify which events in the traced process
242should be reported to the tracing process.
243These events are specified in a
244.Dq Li "struct ptrace_event"
245defined as:
246.Bd -literal -offset indent
247typedef struct ptrace_event {
248	int	pe_set_event;
249} ptrace_event_t;
250.Ed
251.Pp
252Where
253.Fa pe_set_event
254is the set of events to be reported.
255This set is formed by OR'ing together the following values:
256.Bl -tag -width 18n
257.It PTRACE_FORK
258Report
259.Xr fork 2 .
260.El
261.Pp
262A pointer to this structure is passed in
263.Fa addr .
264The
265.Fa data
266argument should be set to
267.Li sizeof(struct ptrace_event) .
268.It Dv PT_GET_EVENT_MASK
269This request can be used to determine which events in the traced
270process will be reported.
271The information is read into the
272.Dq Li struct ptrace_event
273pointed to by
274.Fa addr .
275The
276.Fa data
277argument should be set to
278.Li sizeof(struct ptrace_event) .
279.It Dv PT_GET_PROCESS_STATE
280This request reads the state information associated with the event
281that stopped the traced process.
282The information is reported in a
283.Dq Li "struct ptrace_state"
284defined as:
285.Bd -literal -offset indent
286typedef struct ptrace_state {
287	int	pe_report_event;
288	pid_t	pe_other_pid;
289} ptrace_state_t;
290.Ed
291.Pp
292Where
293.Fa pe_report_event
294is the event being reported.
295If the event being reported is
296.Dv PTRACE_FORK ,
297.Fa pe_other_pid
298will be set to the process ID of the other end of the fork.
299A pointer to this structure is passed in
300.Fa addr .
301The
302.Fa data
303argument should be set to
304.Li sizeof(struct ptrace_state) .
305.It Dv PT_GET_THREAD_FIRST
306This request reads the thread ID of the traced process' first thread into the
307.Dq Li struct ptrace_thread_state
308pointed to by
309.Fa addr .
310The
311.Fa data
312argument should be set to
313.Li sizeof(struct ptrace_thread_state) .
314.It Dv PT_GET_THREAD_NEXT
315This request is just like
316.Dv PT_GET_THREAD_FIRST ,
317except it returns the thread ID of the subsequent thread.
318The
319.Dq Li struct ptrace_thread_state
320pointed to by
321.Fa addr
322must be initialized by a previous
323.Dv PT_GET_THREAD_FIRST
324or
325.Dv PT_GET_THREAD_NEXT
326request.
327.El
328.Pp
329Additionally, machine-specific requests can exist.
330Depending on the architecture, the following requests may be available
331under
332.Ox :
333.Bl -tag -width 12n
334.It Dv PT_GETREGS Pq all platforms
335This request reads the traced process' machine registers into the
336.Dq Li struct reg
337(defined in
338.In machine/reg.h )
339pointed to by
340.Fa addr .
341.It Dv PT_SETREGS Pq all platforms
342This request is the converse of
343.Dv PT_GETREGS ;
344it loads the traced process' machine registers from the
345.Dq Li struct reg
346(defined in
347.In machine/reg.h )
348pointed to by
349.Fa addr .
350.\" .It Dv PT_SYSCALL
351.\" This request is like
352.\" .Dv PT_CONTINUE
353.\" except that the process will stop next time it executes any system
354.\" call.
355.\" Information about the system call can be examined with
356.\" .Dv PT_READ_U
357.\" and potentially modified with
358.\" .Dv PT_WRITE_U
359.\" through the
360.\" .Li u_kproc.kp_proc.p_md
361.\" element of the user structure (see below).
362.\" If the process is continued with another
363.\" .Dv PT_SYSCALL
364.\" request, it will stop again on exit from the syscall, at which point
365.\" the return values can be examined and potentially changed.
366.\" The
367.\" .Li u_kproc.kp_proc.p_md
368.\" element is of type
369.\" .Dq Li struct mdproc ,
370.\" which should be declared by including
371.\" .In sys/param.h ,
372.\" .In sys/user.h ,
373.\" and
374.\" .In machine/proc.h ,
375.\" and contains the following fields (among others):
376.\" .Bl -item -compact -offset indent
377.\" .It
378.\" .Li syscall_num
379.\" .It
380.\" .Li syscall_nargs
381.\" .It
382.\" .Li syscall_args[8]
383.\" .It
384.\" .Li syscall_err
385.\" .It
386.\" .Li syscall_rv[2]
387.\" .El
388.\" When a process stops on entry to a syscall,
389.\" .Li syscall_num
390.\" holds the number of the syscall,
391.\" .Li syscall_nargs
392.\" holds the number of arguments it expects, and
393.\" .Li syscall_args
394.\" holds the arguments themselves.
395.\" (Only the first
396.\" .Li syscall_nargs
397.\" elements of
398.\" .Li syscall_args
399.\" are guaranteed to be useful.)  When a process stops on exit from a
400.\" syscall,
401.\" .Li syscall_num
402.\" is
403.\" .Li -1 ,
404.\" .Li syscall_err
405.\" holds the error number
406.\" .Po
407.\" see
408.\" .Xr errno 2
409.\" .Pc ,
410.\" or 0 if no error occurred, and
411.\" .Li syscall_rv
412.\" holds the return values.
413.\" (If the syscall returns only one value, only
414.\" .Li syscall_rv[0]
415.\" is useful.)
416.\" The tracing process can modify any of these with
417.\" .Dv PT_WRITE_U ;
418.\" only some modifications are useful.
419.\" .Pp
420.\" On entry to a syscall,
421.\" .Li syscall_num
422.\" can be changed, and the syscall actually performed will correspond to
423.\" the new number (it is the responsibility of the tracing process to fill
424.\" in
425.\" .Li syscall_args
426.\" appropriately for the new call, but there is no need to modify
427.\" .Li syscall_nargs ) .
428.\" If the new syscall number is 0, no syscall is actually performed;
429.\" instead,
430.\" .Li syscall_err
431.\" and
432.\" .Li syscall_rv
433.\" are passed back to the traced process directly (and therefore should be
434.\" filled in).
435.\" If the syscall number is otherwise out of range, a dummy
436.\" syscall which simply produces an
437.\" .Er ENOSYS
438.\" error is effectively performed.
439.\" .Pp
440.\" On exit from a syscall, only
441.\" .Li syscall_err
442.\" and
443.\" .Li syscall_rv
444.\" can usefully be changed; they are set to the values returned by the
445.\" syscall and will be passed back to the traced process by the normal
446.\" syscall return mechanism.
447.It Xo Dv PT_STEP
448.No (not available on sparc64)
449.Xc
450The traced process continues execution, as in request
451.Dv PT_CONTINUE ;
452however, execution stops as soon as possible after execution of at least
453one instruction
454.Pq single-step .
455.\" mips64 (fp registers in the main reg structure)
456.It Xo Dv PT_GETFPREGS
457.No (not available on luna88k or mips64)
458.Xc
459This request reads the traced process' floating-point registers into
460the
461.Dq Li struct fpreg
462(defined in
463.In machine/reg.h )
464pointed to by
465.Fa addr .
466.It Xo Dv PT_SETFPREGS
467.No (not available on luna88k or mips64)
468.Xc
469This request is the converse of
470.Dv PT_GETFPREGS ;
471it loads the traced process' floating-point registers from the
472.Dq Li struct fpreg
473(defined in
474.In machine/reg.h )
475pointed to by
476.Fa addr .
477.It Dv PT_GETXMMREGS Pq i386 only
478This request reads the traced process' XMM registers into the
479.Dq Li struct xmmregs
480(defined in
481.In machine/reg.h )
482pointed to by
483.Fa addr .
484.It Dv PT_SETXMMREGS Pq i386 only
485This request is the converse of
486.Dv PT_GETXMMREGS ;
487it loads the traced process' XMM registers from the
488.Dq Li struct xmmregs
489(defined in
490.In machine/reg.h )
491pointed to by
492.Fa addr .
493.It Dv PT_WCOOKIE Pq sparc64 only
494This request reads the traced process'
495.Sq window cookie
496into the
497.Vt int
498pointed to by
499.Fa addr .
500The window cookie needs to be
501.Sq XOR'ed
502to stack-saved program counters.
503.El
504.Sh ERRORS
505Some requests can cause
506.Fn ptrace
507to return
508.Li -1
509as a non-error value; to disambiguate,
510.Va errno
511is set to zero and this should be checked.
512The possible errors are:
513.Bl -tag -width 4n
514.It Bq Er ESRCH
515No process having the specified process ID exists.
516.It Bq Er EINVAL
517.Bl -bullet -compact
518.It
519A process attempted to use
520.Dv PT_ATTACH
521on itself.
522.It
523The
524.Fa request
525was not one of the legal requests.
526.\" .It
527.\" The
528.\" .Fa addr
529.\" to
530.\" .Dv PT_READ_U
531.\" or
532.\" .Dv PT_WRITE_U
533.\" was not
534.\" .Li int Ns \&-aligned.
535.It
536The signal number (in
537.Fa data )
538to
539.Dv PT_CONTINUE
540.\" or
541.\" .Dv PT_SYSCALL
542was neither 0 nor a legal signal number.
543.It
544.Dv PT_GETREGS ,
545.Dv PT_SETREGS ,
546.Dv PT_GETFPREGS ,
547or
548.Dv PT_SETFPREGS
549was attempted on a process with no valid register set.
550(This is normally true only of system processes.)
551.El
552.It Bq Er EBUSY
553.Bl -bullet -compact
554.It
555.Dv PT_ATTACH
556was attempted on a process that was already being traced.
557.It
558A request attempted to manipulate a process that was being traced by
559some process other than the one making the request.
560.It
561A request (other than
562.Dv PT_ATTACH )
563specified a process that wasn't stopped and waited for.
564.El
565.It Bq Er EPERM
566.Bl -bullet -compact
567.It
568A request (other than
569.Dv PT_ATTACH )
570attempted to manipulate a process that wasn't being traced at all.
571.It
572An attempt was made to use
573.Dv PT_ATTACH
574on a process in violation of the requirements listed under
575.Dv PT_ATTACH
576above.
577.It
578An attempt was made to use
579.Dv PT_ATTACH
580on a system process.
581.El
582.El
583.Sh HISTORY
584The
585.Fn ptrace
586system call first appeared in
587.At v6 .
588.Sh BUGS
589On several RISC architectures (such as luna88k and sparc64),
590the PC is set to the provided PC value for
591.Dv PT_CONTINUE
592and similar calls, and the remainder of the execution pipeline registers
593are set to the following instructions, even if the instruction at PC
594is a branch instruction.
595Using
596.Dv PT_GETREGS
597and
598.Dv PT_SETREGS
599to modify the PC, passing
600.Li (caddr_t)1
601to
602.Fn ptrace ,
603should be able to sidestep this.
604.\" .Pp
605.\" When using
606.\" .Dv PT_SYSCALL ,
607.\" there is no easy way to tell whether the traced process stopped because
608.\" it made a syscall or because a signal was sent at a moment that it just
609.\" happened to have valid-looking garbage in its
610.\" .Dq Li struct mdproc .
611