1.\" $NetBSD: ptrace.2,v 1.1 1994/11/14 06:26:46 deraadt Exp $ 2.\" This file is in the public domain. 3.Dd November 7, 1994 4.Dt PTRACE 2 5.Os NetBSD 1.0BETA 6.Sh NAME 7.Nm ptrace 8.Nd process tracing and debugging 9.Sh SYNOPSIS 10.Fd #include <sys/types.h> 11.Fd #include <sys/ptrace.h> 12.Ft int 13.Fn ptrace "int request" "pid_t pid" "caddr_t addr" "int data" 14.Sh DESCRIPTION 15.Fn ptrace 16provides tracing and debugging facilities. It allows one process (the 17.Em tracing 18process) to control another (the 19.Em traced 20process). Most of the time, the traced process runs normally, but when 21it receives a signal 22.Po 23see 24.Xr sigaction 2 25.Pc , 26it stops. The tracing process is expected to notice this via 27.Xr wait 2 28or the delivery of a 29.Dv SIGCHLD 30signal, examine the state of the stopped process, and cause it to 31terminate or continue as appropriate. 32.Fn ptrace 33is the mechanism by which all this happens. 34.Pp 35The 36.Fa request 37argument specifies what operation is being performed; the meaning of 38the rest of the arguments depends on the operation, but except for one 39special case noted below, all 40.Fn ptrace 41calls are made by the tracing process, and the 42.Fa pid 43argument specifies the process ID of the traced process. 44.Fa request 45can be: 46.Bl -tag -width 12n 47.It Dv PT_TRACE_ME 48This request is the only one used by the traced process; it declares 49that the process expects to be traced by its parent. All the other 50arguments are ignored. (If the parent process does not expect to trace 51the child, it will probably be rather confused by the results; once the 52traced process stops, it cannot be made to continue except via 53.Eo \& 54.Fn ptrace 55.Ec \&.) 56When a process has used this request and calls 57.Xr execve 2 58or any of the routines built on it 59.Po 60such as 61.Xr execv 3 62.Pc , 63it will stop before executing the first instruction of the new image. 64Also, any setuid or setgid bits on the executable being executed will 65be ignored. 66.It Dv PT_READ_I , Dv PT_READ_D 67These requests read a single 68.Li int 69of data from the traced process' address space. Traditionally, 70.Fn ptrace 71has allowed for machines with distinct address spaces for instruction 72and data, which is why there are two requests: conceptually, 73.Dv PT_READ_I 74reads from the instruction space and 75.Dv PT_READ_D 76reads from the data space. In the current NetBSD implementation, these 77two requests are completely identical. The 78.Fa addr 79argument specifies the address (in the traced process' virtual address 80space) at which the read is to be done. This address does not have to 81meet any alignment constraints. The value read is returned as the 82return value from 83.Eo \& 84.Fn ptrace 85.Ec . 86.It Dv PT_WRITE_I , Dv PT_WRITE_D 87These requests parallel 88.Dv PT_READ_I 89and 90.Dv PT_READ_D , 91except that they write rather than read. The 92.Fa data 93argument supplies the value to be written. 94.It Dv PT_READ_U 95This request reads an 96.Li int 97from the traced process' user structure. The 98.Fa addr 99argument specifies the location of the int relative to the base of the 100user structure; it will usually be an integer value cast to 101.Li caddr_t 102either explicitly or via the presence of a prototype for 103.Eo \& 104.Fn ptrace 105.Ec . 106Unlike 107.Dv PT_READ_I 108and 109.Dv PT_READ_D , 110.Fa addr 111must be aligned on an 112.Li int 113boundary. The value read is returned as the return value from 114.Eo \& 115.Fn ptrace 116.Ec . 117.It Dv PT_WRITE_U 118This request writes an 119.Li int 120into the traced process' user structure. 121.Fa addr 122specifies the offset, just as for 123.Dv PT_READ_U , 124and 125.Fa data 126specifies the value to be written, just as for 127.Dv PT_WRITE_I 128and 129.Dv PT_WRITE_D . 130.It Dv PT_CONTINUE 131The traced process continues execution. 132.Fa addr 133is an address specifying the place where execution is to be resumed (a 134new value for the program counter), or 135.Li (caddr_t)1 136to indicate that execution is to pick up where it left off. 137.Fa data 138provides a signal number to be delivered to the traced process as it 139resumes execution, or 0 if no signal is to be sent. 140.It Dv PT_KILL 141The traced process terminates, as if 142.Dv PT_CONTINUE 143had been used with 144.Dv SIGKILL 145given as the signal to be delivered. 146.It Dv PT_ATTACH 147This request allows a process to gain control of an otherwise unrelated 148process and begin tracing it. It does not need any cooperation from 149the to-be-traced process. In this case, 150.Fa pid 151specifies the process ID of the to-be-traced process, and the other two 152arguments are ignored. This request requires that the target process 153must have the same real UID as the tracing process, and that it must 154not be executing a setuid or setgid executable. (If the tracing 155process is running as root, these restrictions do not apply.) The 156tracing process will see the newly-traced process stop and may then 157control it as if it had been traced all along. 158.It Dv PT_DETACH 159This request is like PT_CONTINUE, except that it does not allow 160specifying an alternate place to continue execution, and after it 161succeeds, the traced process is no longer traced and continues 162execution normally. 163.El 164.Pp 165Additionally, machine-specific requests can exist. On the SPARC, these 166are: 167.Bl -tag -width 12n 168.It Dv PT_GETREGS 169This request reads the traced process' machine registers into the 170.Dq Li "struct reg" 171(defined in 172.Aq Pa machine/reg.h ) 173pointed to by 174.Fa addr . 175.It Dv PT_SETREGS 176This request is the converse of 177.Dv PT_GETREGS ; 178it loads the traced process' machine registers from the 179.Dq Li "struct reg" 180(defined in 181.Aq Pa machine/reg.h ) 182pointed to by 183.Fa addr . 184.It Dv PT_GETFPREGS 185This request reads the traced process' floating-point registers into 186the 187.Dq Li "struct fpreg" 188(defined in 189.Aq Pa machine/reg.h ) 190pointed to by 191.Fa addr . 192.It Dv PT_SETFPREGS 193This request is the converse of 194.Dv PT_GETFPREGS ; 195it loads the traced process' floating-point registers from the 196.Dq Li "struct fpreg" 197(defined in 198.Aq Pa machine/reg.h ) 199pointed to by 200.Fa addr . 201.It Dv PT_SYSCALL 202This request is like 203.Dv PT_CONTINUE 204except that the process will stop next time it executes any system 205call. Information about the system call can be examined with 206.Dv PT_READ_U 207and potentially modified with 208.Dv PT_WRITE_U 209through the 210.Li u_kproc.kp_proc.p_md 211element of the user structure (see below). If the process is continued 212with another 213.Dv PT_SYSCALL 214request, it will stop again on exit from the syscall, at which point 215the return values can be examined and potentially changed. The 216.Li u_kproc.kp_proc.p_md 217element is of type 218.Dq Li "struct mdproc" , 219which should be declared by including 220.Aq Pa sys/param.h , 221.Aq Pa sys/user.h , 222and 223.Aq Pa machine/proc.h , 224and contains the following fields (among others): 225.Bl -item -compact -offset indent 226.It 227.Li syscall_num 228.It 229.Li syscall_nargs 230.It 231.Li syscall_args[8] 232.It 233.Li syscall_err 234.It 235.Li syscall_rv[2] 236.El 237When a process stops on entry to a syscall, 238.Li syscall_num 239holds the number of the syscall, 240.Li syscall_nargs 241holds the number of arguments it expects, and 242.Li syscall_args 243holds the arguments themselves. (Only the first 244.Li syscall_nargs 245elements of 246.Li syscall_args 247are guaranteed to be useful.) When a process stops on exit from a 248syscall, 249.Li syscall_num 250is 251.Eo \& 252.Li -1 253.Ec , 254.Li syscall_err 255holds the error number 256.Po 257see 258.Xr errno 2 259.Pc , 260or 0 if no error occurred, and 261.Li syscall_rv 262holds the return values. (If the syscall returns only one value, only 263.Li syscall_rv[0] 264is useful.) The tracing process can modify any of these with 265.Dv PT_WRITE_U ; 266only some modifications are useful. 267.Pp 268On entry to a syscall, 269.Li syscall_num 270can be changed, and the syscall actually performed will correspond to 271the new number (it is the responsibility of the tracing process to fill 272in 273.Li syscall_args 274appropriately for the new call, but there is no need to modify 275.Eo \& 276.Li syscall_nargs 277.Ec ). 278If the new syscall number is 0, no syscall is actually performed; 279instead, 280.Li syscall_err 281and 282.Li syscall_rv 283are passed back to the traced process directly (and therefore should be 284filled in). If the syscall number is otherwise out of range, a dummy 285syscall which simply produces an 286.Er ENOSYS 287error is effectively performed. 288.Pp 289On exit from a syscall, only 290.Li syscall_err 291and 292.Li syscall_rv 293can usefully be changed; they are set to the values returned by the 294syscall and will be passed back to the traced process by the normal 295syscall return mechanism. 296.El 297.Sh ERRORS 298Some requests can cause 299.Fn ptrace 300to return 301.Li -1 302as a non-error value; to disambiguate, 303.Va errno 304can be set to 0 before the call and checked afterwards. The possible 305errors are: 306.Bl -tag -width 4n 307.It Bq Er ESRCH 308No process having the specified process ID exists. 309.It Bq Er EINVAL 310.Bl -bullet -compact 311.It 312A process attempted to use 313.Dv PT_ATTACH 314on itself. 315.It 316The 317.Fa request 318was not one of the legal requests. 319.It 320The 321.Fa addr 322to 323.Dv PT_READ_U 324or 325.Dv PT_WRITE_U 326was not 327.Li int Ns \&-aligned. 328.It 329The signal number (in 330.Fa data ) 331to 332.Dv PT_CONTINUE 333or 334.Dv PT_SYSCALL 335was neither 0 nor a legal signal number. 336.It 337.Dv PT_GETREGS , 338.Dv PT_SETREGS , 339.Dv PT_GETFPREGS , 340or 341.Dv PT_SETFPREGS 342was attempted on a process with no valid register set. (This is 343normally true only of system processes.) 344.El 345.It Bq Er EBUSY 346.Bl -bullet -compact 347.It 348.Dv PT_ATTACH 349was attempted on a process that was already being traced. 350.It 351A request attempted to manipulate a process that was being traced by 352some process other than the one making the request. 353.It 354A request (other than 355.Dv PT_ATTACH ) 356specified a process that wasn't stopped. 357.El 358.It Bq Er EPERM 359.Bl -bullet -compact 360.It 361A request (other than 362.Dv PT_ATTACH ) 363attempted to manipulate a process that wasn't being traced at all. 364.It 365An attempt was made to use 366.Dv PT_ATTACH 367on a process in violation of the requirements listed under 368.Dv PT_ATTACH 369above. 370.El 371.Sh BUGS 372On the SPARC, the PC is set to the provided PC value for 373.Dv PT_CONTINUE 374and similar calls, but the NPC is set willy-nilly to 4 greater than the 375PC value. Using 376.Dv PT_GETREGS 377and 378.Dv PT_SETREGS 379to modify the PC, passing 380.Li (caddr_t)1 381to 382.Eo \& 383.Fn ptrace 384.Ec , 385should be able to sidestep this. 386.Pp 387Single-stepping is not available. 388.Pp 389When using 390.Dv PT_SYSCALL , 391there is no easy way to tell whether the traced process stopped because 392it made a syscall or because a signal was sent at a moment that it just 393happened to have valid-looking garbage in its 394.Dq Li "struct mdproc" . 395