Added possibility to wait on syscalls
This commit is contained in:
parent
c3d2944311
commit
c968c0d09a
|
|
@ -42,8 +42,10 @@ impl DebugState for Stopped {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl DebugTarget<Stopped> {
|
impl DebugTarget<Stopped> {
|
||||||
pub fn new(pid: Pid) -> Result<Self, WaitError> {
|
pub fn new(pid: Pid) -> Result<Self, DebugError> {
|
||||||
waitid(Id::Pid(pid), WaitPidFlag::WSTOPPED).map_err(WaitError)?;
|
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 } })
|
Ok(DebugTarget { state: Stopped { pid } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,6 +59,11 @@ impl DebugTarget<Stopped> {
|
||||||
Ok(DebugTarget { state: Running { pid: self.state.pid } })
|
Ok(DebugTarget { state: Running { pid: self.state.pid } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cont_syscall(self) -> Result<DebugTarget<Running>, 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<user_regs_struct, PTraceError> {
|
pub fn get_registers(&self) -> Result<user_regs_struct, PTraceError> {
|
||||||
Ok(nix::sys::ptrace::getregs(self.state.pid)?)
|
Ok(nix::sys::ptrace::getregs(self.state.pid)?)
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +82,14 @@ impl DebugTarget<Running> {
|
||||||
pub fn wait_for_something(self) -> Result<Either<DebugTarget<Stopped>, i32>, DebugError> {
|
pub fn wait_for_something(self) -> Result<Either<DebugTarget<Stopped>, i32>, DebugError> {
|
||||||
match waitid(Id::Pid(self.state.pid), WaitPidFlag::WSTOPPED | WaitPidFlag::WEXITED).map_err(WaitError)? {
|
match waitid(Id::Pid(self.state.pid), WaitPidFlag::WSTOPPED | WaitPidFlag::WEXITED).map_err(WaitError)? {
|
||||||
WaitStatus::Exited(_pid, exit_code) => Ok(Right(exit_code)),
|
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<DebugTarget<Stopped>, 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)),
|
status => Err(DebugError::UnexpectedWaitStatus(status)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue