v0.2: prev snapshot of regs, refactored state/prev to share build_register_view

This commit is contained in:
claude
2026-05-27 21:10:23 +00:00
parent 912f5003fe
commit 19c6154831
2 changed files with 91 additions and 54 deletions
+11
View File
@@ -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 {