1.\" $OpenBSD: ptrace.2,v 1.44 2024/11/27 05:25:56 anton 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: November 27 2024 $ 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.It Dv PT_GETXSTATE_INFO Pq amd64 only 504This request can be used to obtain details about the traced process XSAVE area, 505specified in a 506.Dq Li "struct ptrace_xstate_info" 507defined as follows: 508.Bd -literal -offset indent 509struct ptrace_xstate_info { 510 uint64_t xsave_mask; 511 uint32_t xsave_len; 512}; 513.Ed 514.Pp 515The 516.Fa xsave_mask 517field denotes the enabled XSAVE components. 518The 519.Fa xsave_len 520field denotes the size of XSAVE area intended to be used with the 521.Dv PT_GETXSTATE 522and 523.Dv PT_SETXSTATE 524requests. 525.Pp 526A pointer to 527.Dq Li "struct ptrace_xstate_info" 528must be passed in 529.Fa addr 530and the 531.Fa data 532argument must be set to 533.Li sizeof(struct ptrace_xstate_info) . 534.It Dv PT_GETXSTATE Pq amd64 only 535This request can be used to read the XSAVE area of the traced process. 536A pointer to a buffer must be passed in 537.Fa addr 538with a capacity of the length obtained using the 539.Dv PT_GETXSTATE_INFO 540request. 541The 542.Fa data 543argument must reflect the same length. 544.It Dv PT_SETXSTATE Pq amd64 only 545This request can be used to write the XSAVE area of the traced process. 546Only changes to the x87, SSE and AVX state components are honored. 547A pointer to a buffer must be passed in 548.Fa addr 549with a capacity of the length obtained using the 550.Dv PT_GETXSTATE_INFO 551request. 552The 553.Fa data 554argument must reflect the same length. 555.El 556.Sh ERRORS 557Some requests can cause 558.Fn ptrace 559to return 560.Li -1 561as a non-error value; to disambiguate, 562.Va errno 563is set to zero and this should be checked. 564The possible errors are: 565.Bl -tag -width 4n 566.It Bq Er ESRCH 567No process having the specified process ID exists. 568.It Bq Er EINVAL 569.Bl -bullet -compact 570.It 571A process attempted to use 572.Dv PT_ATTACH 573on itself. 574.It 575The 576.Fa request 577was not one of the legal requests. 578.\" .It 579.\" The 580.\" .Fa addr 581.\" to 582.\" .Dv PT_READ_U 583.\" or 584.\" .Dv PT_WRITE_U 585.\" was not 586.\" .Li int Ns \&-aligned. 587.It 588The signal number (in 589.Fa data ) 590to 591.Dv PT_CONTINUE 592.\" or 593.\" .Dv PT_SYSCALL 594was neither 0 nor a legal signal number. 595.It 596.Dv PT_GETREGS , 597.Dv PT_SETREGS , 598.Dv PT_GETFPREGS , 599or 600.Dv PT_SETFPREGS 601was attempted on a process with no valid register set. 602(This is normally true only of system processes.) 603.El 604.It Bq Er EBUSY 605.Bl -bullet -compact 606.It 607.Dv PT_ATTACH 608was attempted on a process that was already being traced. 609.It 610A request attempted to manipulate a process that was being traced by 611some process other than the one making the request. 612.It 613A request (other than 614.Dv PT_ATTACH ) 615specified a process that wasn't stopped and waited for. 616.El 617.It Bq Er EPERM 618.Bl -bullet -compact 619.It 620A request (other than 621.Dv PT_ATTACH ) 622attempted to manipulate a process that wasn't being traced at all. 623.It 624An attempt was made to use 625.Dv PT_ATTACH 626on a process in violation of the requirements listed under 627.Dv PT_ATTACH 628above. 629.It 630An attempt was made to use 631.Dv PT_ATTACH 632on a system process. 633.El 634.It Bq Er ENOTSUP 635.Dv PT_GETXSTATE_INFO , 636.Dv PT_GETXSTATE , 637or 638.Dv PT_SETXSTATE 639was attempted on a CPU lacking support for XSAVE. 640.El 641.Sh HISTORY 642The 643.Fn ptrace 644system call first appeared in 645.At v6 . 646.Sh BUGS 647On several RISC architectures (such as luna88k and sparc64), 648the PC is set to the provided PC value for 649.Dv PT_CONTINUE 650and similar calls, and the remainder of the execution pipeline registers 651are set to the following instructions, even if the instruction at PC 652is a branch instruction. 653Using 654.Dv PT_GETREGS 655and 656.Dv PT_SETREGS 657to modify the PC, passing 658.Li (caddr_t)1 659to 660.Fn ptrace , 661should be able to sidestep this. 662.\" .Pp 663.\" When using 664.\" .Dv PT_SYSCALL , 665.\" there is no easy way to tell whether the traced process stopped because 666.\" it made a syscall or because a signal was sent at a moment that it just 667.\" happened to have valid-looking garbage in its 668.\" .Dq Li struct mdproc . 669