v0.2: prev snapshot of regs, refactored state/prev to share build_register_view
This commit is contained in:
@@ -52,6 +52,9 @@ pub enum State {
|
||||
pub struct Target {
|
||||
pid: Pid,
|
||||
state: State,
|
||||
/// Snapshot of registers from the previous stop. None until at least one
|
||||
/// step/cont has happened after spawn.
|
||||
prev_regs: Option<libc::user_regs_struct>,
|
||||
}
|
||||
|
||||
impl Target {
|
||||
@@ -102,6 +105,7 @@ impl Target {
|
||||
WaitStatus::Stopped(_, Signal::SIGTRAP) => Ok(Target {
|
||||
pid: child,
|
||||
state: State::Stopped(StopReason::Step),
|
||||
prev_regs: None,
|
||||
}),
|
||||
WaitStatus::Exited(_, code) => {
|
||||
Err(format!("child exited immediately with code {} (exec failed?)", code))
|
||||
@@ -117,6 +121,8 @@ impl Target {
|
||||
if !self.is_stopped() {
|
||||
return Err("target is not stopped".into());
|
||||
}
|
||||
// Snapshot regs before resuming so `prev` reflects the pre-step state.
|
||||
self.prev_regs = ptrace::getregs(self.pid).ok();
|
||||
ptrace::step(self.pid, None).map_err(|e| format!("ptrace step: {}", e))?;
|
||||
let reason = self.wait_for_stop()?;
|
||||
Ok(reason)
|
||||
@@ -127,11 +133,16 @@ impl Target {
|
||||
if !self.is_stopped() {
|
||||
return Err("target is not stopped".into());
|
||||
}
|
||||
self.prev_regs = ptrace::getregs(self.pid).ok();
|
||||
ptrace::cont(self.pid, None).map_err(|e| format!("ptrace cont: {}", e))?;
|
||||
let reason = self.wait_for_stop()?;
|
||||
Ok(reason)
|
||||
}
|
||||
|
||||
pub fn prev_regs(&self) -> Option<libc::user_regs_struct> {
|
||||
self.prev_regs
|
||||
}
|
||||
|
||||
fn wait_for_stop(&mut self) -> Result<StopReason, String> {
|
||||
let status = waitpid(self.pid, None).map_err(|e| format!("waitpid: {}", e))?;
|
||||
let reason = match status {
|
||||
|
||||
Reference in New Issue
Block a user