diff --git a/proj-1/deet/src/debugger.rs b/proj-1/deet/src/debugger.rs index 42e1782..36f1b9c 100644 --- a/proj-1/deet/src/debugger.rs +++ b/proj-1/deet/src/debugger.rs @@ -1,5 +1,5 @@ use crate::debugger_command::DebuggerCommand; -use crate::inferior::Inferior; +use crate::inferior::{Inferior, Status}; use rustyline::error::ReadlineError; use rustyline::Editor; @@ -35,9 +35,20 @@ impl Debugger { if let Some(inferior) = Inferior::new(&self.target, &args) { // Create the inferior self.inferior = Some(inferior); - // TODO (milestone 1): make the inferior run // You may use self.inferior.as_mut().unwrap() to get a mutable reference // to the Inferior object + let res = self.inferior.as_mut().unwrap().cont(); + if let Ok(res) = res { + match res { + Status::Exited(exit_status) => { + println!("Child exited (statuss {})", exit_status); + }, + Status::Signaled(_) => (), + Status::Stopped(_, _) => (), + } + } else { + eprintln!("Error running(continue) subprocess"); + } } else { println!("Error starting subprocess"); } diff --git a/proj-1/deet/src/inferior.rs b/proj-1/deet/src/inferior.rs index b87a142..25421c8 100644 --- a/proj-1/deet/src/inferior.rs +++ b/proj-1/deet/src/inferior.rs @@ -1,8 +1,11 @@ use nix::sys::ptrace; use nix::sys::signal; +use nix::sys::signal::Signal; use nix::sys::wait::{waitpid, WaitPidFlag, WaitStatus}; use nix::unistd::Pid; +use std::os::unix::process::CommandExt; use std::process::Child; +use std::process::Command; pub enum Status { /// Indicates inferior stopped. Contains the signal that stopped the process, as well as the @@ -34,12 +37,31 @@ impl Inferior { /// Attempts to start a new inferior process. Returns Some(Inferior) if successful, or None if /// an error is encountered. pub fn new(target: &str, args: &Vec) -> Option { - // TODO: implement me! - println!( - "Inferior::new not implemented! target={}, args={:?}", - target, args - ); - None + let mut child_cmd = Command::new(target); + child_cmd.args(args); + unsafe { + child_cmd.pre_exec(child_traceme); + } + let child = child_cmd + .spawn() + .expect(format!("Failed to spawn subprocess using command {target}").as_str()); + let child_pid = nix::unistd::Pid::from_raw(child.id() as i32); + let fucker = waitpid(child_pid, Some(WaitPidFlag::WSTOPPED)).ok()?; + if let WaitStatus::Stopped(_, signal) = fucker { + if signal != Signal::SIGTRAP { + eprintln!("child stopped by {}, expected SIGTRAP", signal); + return None; + } + } + else { + eprintln!("child at status ?, expected to stop"); + return None; + } + // println!( + // "Inferior::new not implemented! target={}, args={:?}", + // target, args + // ); + Some(Inferior {child}) } /// Returns the pid of this inferior. @@ -60,4 +82,9 @@ impl Inferior { other => panic!("waitpid returned unexpected status: {:?}", other), }) } + + pub fn cont(&self) -> Result { + ptrace::cont(self.pid(), None)?; + self.wait(None) + } }