diff --git a/src/debug_target.rs b/src/debug_target.rs index 724081d..9f6a756 100644 --- a/src/debug_target.rs +++ b/src/debug_target.rs @@ -42,8 +42,10 @@ impl DebugState for Stopped { #[allow(dead_code)] impl DebugTarget { - pub fn new(pid: Pid) -> Result { + pub fn new(pid: Pid) -> Result { waitid(Id::Pid(pid), WaitPidFlag::WSTOPPED).map_err(WaitError)?; + // Needed for waiting on syscalls and apparently also for getting syscall info (can not get it to work without this) + nix::sys::ptrace::setoptions(pid, nix::sys::ptrace::Options::PTRACE_O_TRACESYSGOOD).map_err(PTraceError)?; Ok(DebugTarget { state: Stopped { pid } }) } @@ -57,6 +59,11 @@ impl DebugTarget { Ok(DebugTarget { state: Running { pid: self.state.pid } }) } + pub fn cont_syscall(self) -> Result, PTraceError> { + nix::sys::ptrace::syscall(self.state.pid, None).map_err(PTraceError)?; + Ok(DebugTarget { state: Running { pid: self.state.pid } }) + } + pub fn get_registers(&self) -> Result { Ok(nix::sys::ptrace::getregs(self.state.pid)?) } @@ -75,7 +82,14 @@ impl DebugTarget { pub fn wait_for_something(self) -> Result, i32>, DebugError> { match waitid(Id::Pid(self.state.pid), WaitPidFlag::WSTOPPED | WaitPidFlag::WEXITED).map_err(WaitError)? { WaitStatus::Exited(_pid, exit_code) => Ok(Right(exit_code)), - WaitStatus::PtraceEvent(_pid, _signal, _c_event) => Ok(Left(DebugTarget { state: Stopped { pid: self.state.pid } })), + WaitStatus::PtraceEvent(..) | WaitStatus::PtraceSyscall(..) => Ok(Left(DebugTarget { state: Stopped { pid: self.state.pid } })), + status => Err(DebugError::UnexpectedWaitStatus(status)), + } + } + + pub fn wait_for_syscall(self) -> Result, DebugError> { + match waitid(Id::Pid(self.state.pid), WaitPidFlag::WSTOPPED).map_err(WaitError)? { + WaitStatus::PtraceSyscall(..) => Ok(DebugTarget { state: Stopped { pid: self.state.pid } }), status => Err(DebugError::UnexpectedWaitStatus(status)), } }