Starting some kind of custom interface
This commit is contained in:
parent
90dbe285d6
commit
f74e9ef01c
|
|
@ -0,0 +1,48 @@
|
|||
use nix::errno::Errno;
|
||||
use nix::sys::wait::{waitid, Id, WaitPidFlag, WaitStatus};
|
||||
use nix::unistd::Pid;
|
||||
|
||||
pub struct DebugTarget<S: DebugState> {
|
||||
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<Stopped> {
|
||||
pub fn new(pid: Pid) -> Result<Self, Errno> {
|
||||
waitid(Id::Pid(pid), WaitPidFlag::WSTOPPED).and(Ok(DebugTarget { state: Stopped { pid } }))
|
||||
}
|
||||
|
||||
pub fn cont(self) -> Result<DebugTarget<Running>, 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<Running> {
|
||||
pub fn wait_for_exit(self) -> Result<i32, Errno> {
|
||||
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?
|
||||
})
|
||||
}
|
||||
}
|
||||
17
src/main.rs
17
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}");
|
||||
|
|
|
|||
Loading…
Reference in New Issue