Skip to main content

stracers_core/platform/
linux.rs

1use nix::libc::user_regs_struct;
2use nix::sys::ptrace;
3use nix::sys::signal::Signal;
4use nix::sys::wait::{WaitPidFlag, WaitStatus, waitpid};
5use nix::unistd::Pid;
6use std::io;
7
8pub fn traceme() -> io::Result<()> {
9    ptrace::traceme().map_err(nix_to_io)
10}
11
12pub fn attach(pid: Pid) -> io::Result<()> {
13    ptrace::attach(pid).map_err(nix_to_io)
14}
15
16pub fn detach(pid: Pid, sig: Option<Signal>) -> io::Result<()> {
17    ptrace::detach(pid, sig).map_err(nix_to_io)
18}
19
20pub fn syscall_continue(pid: Pid, sig: Option<Signal>) -> io::Result<()> {
21    ptrace::syscall(pid, sig).map_err(nix_to_io)
22}
23
24pub fn get_registers(pid: Pid) -> io::Result<user_regs_struct> {
25    ptrace::getregs(pid).map_err(nix_to_io)
26}
27
28pub fn set_options(pid: Pid, options: ptrace::Options) -> io::Result<()> {
29    ptrace::setoptions(pid, options).map_err(nix_to_io)
30}
31
32pub fn wait(pid: Pid) -> io::Result<WaitStatus> {
33    waitpid(pid, None).map_err(nix_to_io)
34}
35
36/// Wait for any traced child. Returns the status of whichever child stopped.
37pub fn wait_any() -> io::Result<WaitStatus> {
38    waitpid(None, Some(WaitPidFlag::__WALL)).map_err(nix_to_io)
39}
40
41pub fn get_event(pid: Pid) -> io::Result<i64> {
42    ptrace::getevent(pid).map_err(nix_to_io).map(|v| v as i64)
43}
44
45pub fn read_word(pid: Pid, addr: u64) -> io::Result<i64> {
46    ptrace::read(pid, addr as *mut _).map_err(nix_to_io)
47}
48
49fn nix_to_io(e: nix::Error) -> io::Error {
50    io::Error::from_raw_os_error(e as i32)
51}