|
| 1 | +//! For detailed description of the ptrace requests, consult `man ptrace`. |
| 2 | +
|
1 | 3 | use std::{mem, ptr};
|
2 | 4 | use {Errno, Error, Result};
|
3 | 5 | use libc::{c_void, c_long, siginfo_t};
|
4 | 6 | use ::unistd::Pid;
|
| 7 | +use sys::signal::Signal; |
5 | 8 |
|
6 | 9 | pub mod ptrace {
|
7 | 10 | use libc::c_int;
|
@@ -70,7 +73,11 @@ mod ffi {
|
70 | 73 |
|
71 | 74 | /// Performs a ptrace request. If the request in question is provided by a specialised function
|
72 | 75 | /// this function will return an unsupported operation error.
|
73 |
| -pub fn ptrace(request: ptrace::PtraceRequest, pid: Pid, addr: *mut c_void, data: *mut c_void) -> Result<c_long> { |
| 76 | +#[deprecated( |
| 77 | + since="0.10.0", |
| 78 | + note="usages of `ptrace()` should be replaced with the specialized helper functions instead" |
| 79 | +)] |
| 80 | +pub unsafe fn ptrace(request: ptrace::PtraceRequest, pid: Pid, addr: *mut c_void, data: *mut c_void) -> Result<c_long> { |
74 | 81 | use self::ptrace::*;
|
75 | 82 |
|
76 | 83 | match request {
|
@@ -103,8 +110,8 @@ fn ptrace_get_data<T>(request: ptrace::PtraceRequest, pid: Pid) -> Result<T> {
|
103 | 110 | Ok(data)
|
104 | 111 | }
|
105 | 112 |
|
106 |
| -fn ptrace_other(request: ptrace::PtraceRequest, pid: Pid, addr: *mut c_void, data: *mut c_void) -> Result<c_long> { |
107 |
| - Errno::result(unsafe { ffi::ptrace(request, pid.into(), addr, data) }).map(|_| 0) |
| 113 | +unsafe fn ptrace_other(request: ptrace::PtraceRequest, pid: Pid, addr: *mut c_void, data: *mut c_void) -> Result<c_long> { |
| 114 | + Errno::result(ffi::ptrace(request, pid.into(), addr, data)).map(|_| 0) |
108 | 115 | }
|
109 | 116 |
|
110 | 117 | /// Set options, as with `ptrace(PTRACE_SETOPTIONS,...)`.
|
@@ -140,3 +147,61 @@ pub fn setsiginfo(pid: Pid, sig: &siginfo_t) -> Result<()> {
|
140 | 147 | Err(e) => Err(e),
|
141 | 148 | }
|
142 | 149 | }
|
| 150 | + |
| 151 | +/// Sets the process as traceable, as with `ptrace(PTRACE_TRACEME, ...)` |
| 152 | +/// |
| 153 | +/// Indicates that this process is to be traced by its parent. |
| 154 | +/// This is the only ptrace request to be issued by the tracee. |
| 155 | +pub fn traceme() -> Result<()> { |
| 156 | + unsafe { |
| 157 | + ptrace_other( |
| 158 | + ptrace::PTRACE_TRACEME, |
| 159 | + Pid::from_raw(0), |
| 160 | + ptr::null_mut(), |
| 161 | + ptr::null_mut(), |
| 162 | + ).map(|_| ()) // ignore the useless return value |
| 163 | + } |
| 164 | +} |
| 165 | + |
| 166 | +/// Ask for next syscall, as with `ptrace(PTRACE_SYSCALL, ...)` |
| 167 | +/// |
| 168 | +/// Arranges for the tracee to be stopped at the next entry to or exit from a system call. |
| 169 | +pub fn syscall(pid: Pid) -> Result<()> { |
| 170 | + unsafe { |
| 171 | + ptrace_other( |
| 172 | + ptrace::PTRACE_SYSCALL, |
| 173 | + pid, |
| 174 | + ptr::null_mut(), |
| 175 | + ptr::null_mut(), |
| 176 | + ).map(|_| ()) // ignore the useless return value |
| 177 | + } |
| 178 | +} |
| 179 | + |
| 180 | +/// Attach to a running process, as with `ptrace(PTRACE_ATTACH, ...)` |
| 181 | +/// |
| 182 | +/// Attaches to the process specified in pid, making it a tracee of the calling process. |
| 183 | +pub fn attach(pid: Pid) -> Result<()> { |
| 184 | + unsafe { |
| 185 | + ptrace_other( |
| 186 | + ptrace::PTRACE_ATTACH, |
| 187 | + pid, |
| 188 | + ptr::null_mut(), |
| 189 | + ptr::null_mut(), |
| 190 | + ).map(|_| ()) // ignore the useless return value |
| 191 | + } |
| 192 | +} |
| 193 | + |
| 194 | +/// Restart the stopped tracee process, as with `ptrace(PTRACE_CONT, ...)` |
| 195 | +/// |
| 196 | +/// Continues the execution of the process with PID `pid`, optionally |
| 197 | +/// delivering a signal specified by `sig`. |
| 198 | +pub fn cont<T: Into<Option<Signal>>>(pid: Pid, sig: T) -> Result<()> { |
| 199 | + let data = match sig.into() { |
| 200 | + Some(s) => s as i32 as *mut c_void, |
| 201 | + None => ptr::null_mut(), |
| 202 | + }; |
| 203 | + unsafe { |
| 204 | + ptrace_other(ptrace::PTRACE_CONT, pid, ptr::null_mut(), data).map(|_| ()) // ignore the useless return value |
| 205 | + } |
| 206 | +} |
| 207 | + |
0 commit comments