From f74e9ef01cd77dbe704e3a003336cccec8259b47 Mon Sep 17 00:00:00 2001 From: Elnath Date: Sat, 19 Apr 2025 01:05:23 +0200 Subject: [PATCH] Starting some kind of custom interface --- src/debug_target.rs | 48 +++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 17 +++++++++++++++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/debug_target.rs diff --git a/src/debug_target.rs b/src/debug_target.rs new file mode 100644 index 0000000..45e701f --- /dev/null +++ b/src/debug_target.rs @@ -0,0 +1,48 @@ +use nix::errno::Errno; +use nix::sys::wait::{waitid, Id, WaitPidFlag, WaitStatus}; +use nix::unistd::Pid; + +pub struct DebugTarget { + state: S, +} + +pub trait DebugState { + #[allow(dead_code)] + fn pid(&self) -> Pid; +} + +pub struct Stopped { + pid: Pid, +} + +impl DebugState for Stopped { + fn pid(&self) -> Pid { self.pid } +} + +impl DebugTarget { + pub fn new(pid: Pid) -> Result { + waitid(Id::Pid(pid), WaitPidFlag::WSTOPPED).and(Ok(DebugTarget { state: Stopped { pid } })) + } + + pub fn cont(self) -> Result, Errno> { + nix::sys::ptrace::cont(self.state.pid, None).and(Ok(DebugTarget { state: Running { pid: self.state.pid } })) + } +} + +pub struct Running { + pid: Pid, +} + +impl DebugState for Running { + fn pid(&self) -> Pid { self.pid } +} + + +impl DebugTarget { + pub fn wait_for_exit(self) -> Result { + waitid(Id::Pid(self.state.pid), WaitPidFlag::WEXITED).and_then(|status| match status { + WaitStatus::Exited(_, exit_code) => Ok(exit_code), + _ => Err(Errno::EINVAL), // TODO: custom error type? + }) + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ccc92fb..92c0ca2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ mod child; +mod debug_target; +use crate::debug_target::DebugTarget; use nix::libc::user_regs_struct; use nix::sys::ptrace::*; use nix::sys::signal::Signal::*; @@ -93,8 +95,21 @@ fn main() -> ExitCode { Ok(ForkResult::Child) => child::starti(child_exec_path), Ok(ForkResult::Parent { child: child_pid }) => { println!("✔️ Created child {child_pid}"); + + let target = DebugTarget::new(child_pid).unwrap(); + println!("✔️ Child ready!"); + + println!("⚙️ Continuing execution"); + let target = target.cont().unwrap(); + let exit_code = target.wait_for_exit().unwrap(); + + println!("👋 Child exited with code {exit_code}"); + + // return single_step_all(child_pid); - return breakpoint_fun(child_pid); + // return breakpoint_fun(child_pid); + + ExitCode::SUCCESS } Err(e) => { println!("❌ Fork failed: {e}");