diff --git a/src/agent/debugger/src/debugger.rs b/src/agent/debugger/src/debugger.rs index 32728e1e9..4f9be87f5 100644 --- a/src/agent/debugger/src/debugger.rs +++ b/src/agent/debugger/src/debugger.rs @@ -238,7 +238,10 @@ impl Debugger { mut command: Command, callbacks: &mut impl DebugEventHandler, ) -> Result<(Self, Child)> { - let child = command.creation_flags(DEBUG_ONLY_THIS_PROCESS).spawn()?; + let child = command + .creation_flags(DEBUG_ONLY_THIS_PROCESS) + .spawn() + .context("debugee failed to start")?; check_winapi(|| unsafe { DebugSetProcessKillOnExit(TRUE) }) .context("Setting DebugSetProcessKillOnExit to TRUE")?; diff --git a/src/agent/onefuzz-agent/src/tasks/coverage/recorder.rs b/src/agent/onefuzz-agent/src/tasks/coverage/recorder.rs index 857ba191f..5b2962ce3 100644 --- a/src/agent/onefuzz-agent/src/tasks/coverage/recorder.rs +++ b/src/agent/onefuzz-agent/src/tasks/coverage/recorder.rs @@ -126,7 +126,7 @@ impl CoverageRecorder { cmd.env(k, v); } - let child = cmd.spawn()?; + let child = cmd.spawn().context("gdb failed to start")?; Ok(child) } @@ -163,7 +163,7 @@ impl CoverageRecorder { cmd.env(k, v); } - let child = cmd.spawn()?; + let child = cmd.spawn().context("cdb.exe failed to start")?; Ok(child) } diff --git a/src/agent/onefuzz-agent/src/tasks/fuzz/generator.rs b/src/agent/onefuzz-agent/src/tasks/fuzz/generator.rs index 140d02bfc..3a2d14ea5 100644 --- a/src/agent/onefuzz-agent/src/tasks/fuzz/generator.rs +++ b/src/agent/onefuzz-agent/src/tasks/fuzz/generator.rs @@ -6,7 +6,7 @@ use crate::tasks::{ heartbeat::*, utils::{self, default_bool_true}, }; -use anyhow::Result; +use anyhow::{Context, Result}; use futures::stream::StreamExt; use onefuzz::{ expand::Expand, @@ -150,7 +150,7 @@ impl GeneratorTask { output_dir: impl AsRef, ) -> Result<()> { utils::reset_tmp_dir(&output_dir).await?; - let mut generator = { + let (mut generator, generator_path) = { let mut expand = Expand::new(); expand .generated_inputs(&output_dir) @@ -179,11 +179,13 @@ impl GeneratorTask { for (k, v) in &self.config.generator_env { generator.env(k, expand.evaluate_value(v)?); } - generator + (generator, generator_path) }; info!("Generating test cases with {:?}", generator); - let output = generator.spawn()?; + let output = generator + .spawn() + .with_context(|| format!("generator failed to start: {}", generator_path))?; monitor_process(output, "generator".to_string(), true, None).await?; Ok(()) diff --git a/src/agent/onefuzz-agent/src/tasks/fuzz/supervisor.rs b/src/agent/onefuzz-agent/src/tasks/fuzz/supervisor.rs index 2b118c8f1..f5097fe04 100644 --- a/src/agent/onefuzz-agent/src/tasks/fuzz/supervisor.rs +++ b/src/agent/onefuzz-agent/src/tasks/fuzz/supervisor.rs @@ -9,7 +9,7 @@ use crate::tasks::{ stats::common::{monitor_stats, StatsFormat}, utils::CheckNotify, }; -use anyhow::{Error, Result}; +use anyhow::{Context, Error, Result}; use onefuzz::{ expand::Expand, fs::{has_files, set_executable, OwnedDir}, @@ -213,7 +213,9 @@ async fn start_supervisor( } info!("starting supervisor '{:?}'", cmd); - let child = cmd.spawn()?; + let child = cmd + .spawn() + .with_context(|| format!("supervisor failed to start: {:?}", cmd))?; Ok(child) } diff --git a/src/agent/onefuzz-supervisor/src/commands.rs b/src/agent/onefuzz-supervisor/src/commands.rs index 65fc32124..fbfeef8ca 100644 --- a/src/agent/onefuzz-supervisor/src/commands.rs +++ b/src/agent/onefuzz-supervisor/src/commands.rs @@ -2,7 +2,7 @@ // Licensed under the MIT License. use crate::auth::Secret; -use anyhow::Result; +use anyhow::{Context, Result}; use onefuzz::machine_id::get_scaleset_name; use std::process::Stdio; use tokio::{fs, io::AsyncWriteExt, process::Command}; @@ -52,9 +52,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> { .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn()? + .spawn() + .context("icacls failed to start")? .wait_with_output() - .await?; + .await + .context("icalcs failed to run")?; if !result.status.success() { bail!( "set authorized_keys ({}) permissions failed: {:?}", @@ -70,9 +72,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> { .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn()? + .spawn() + .context("icacls failed to start")? .wait_with_output() - .await?; + .await + .context("icacls failed to run")?; if !result.status.success() { bail!( "set authorized_keys ({}) permissions failed: {:?}", @@ -92,9 +96,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> { .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn()? + .spawn() + .context("Powershell Get-ACL | Set-ACL failed to start")? .wait_with_output() - .await?; + .await + .context("Powershell Get-ACL | Set-ACL failed to run")?; if !result.status.success() { bail!( "set authorized_keys ({}) permissions failed: {:?}", @@ -137,9 +143,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> { .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn()? + .spawn() + .context("chmod failed to start")? .wait_with_output() - .await?; + .await + .context("chmod failed to run")?; if !result.status.success() { bail!("set $HOME/.ssh permissions failed: {:?}", result); } @@ -159,9 +167,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> { .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::piped()) - .spawn()? + .spawn() + .context("chmod failed to start")? .wait_with_output() - .await?; + .await + .context("chmod failed to run")?; if !result.status.success() { bail!( "set authorized_keys ({}) permissions failed: {:?}", diff --git a/src/agent/onefuzz-supervisor/src/worker.rs b/src/agent/onefuzz-supervisor/src/worker.rs index c3437c61c..4a6ced45b 100644 --- a/src/agent/onefuzz-supervisor/src/worker.rs +++ b/src/agent/onefuzz-supervisor/src/worker.rs @@ -231,7 +231,7 @@ impl IWorkerRunner for WorkerRunner { cmd.stderr(Stdio::piped()); cmd.stdout(Stdio::piped()); - let child = cmd.spawn()?; + let child = cmd.spawn().context("onefuzz-agent failed to start")?; let child = Box::new(child); Ok(child) diff --git a/src/agent/onefuzz/src/az_copy.rs b/src/agent/onefuzz/src/az_copy.rs index 72679dc29..874d33c84 100644 --- a/src/agent/onefuzz/src/az_copy.rs +++ b/src/agent/onefuzz/src/az_copy.rs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -use anyhow::Result; +use anyhow::{Context, Result}; use std::ffi::OsStr; use tokio::process::Command; @@ -21,7 +21,12 @@ pub async fn sync(src: impl AsRef, dst: impl AsRef, delete_dst: bo cmd.arg("--delete-destination"); } - let output = cmd.spawn()?.wait_with_output().await?; + let output = cmd + .spawn() + .context("azcopy failed to start")? + .wait_with_output() + .await + .context("azcopy failed to run")?; if !output.status.success() { let stdout = String::from_utf8_lossy(&output.stdout); let stderr = String::from_utf8_lossy(&output.stderr); @@ -53,7 +58,12 @@ pub async fn copy(src: impl AsRef, dst: impl AsRef, recursive: boo cmd.arg("--recursive=true"); } - let output = cmd.spawn()?.wait_with_output().await?; + let output = cmd + .spawn() + .context("azcopy failed to start")? + .wait_with_output() + .await + .context("azcopy failed to run")?; if !output.status.success() { let stdout = String::from_utf8_lossy(&output.stdout); let stderr = String::from_utf8_lossy(&output.stderr); diff --git a/src/agent/onefuzz/src/fs.rs b/src/agent/onefuzz/src/fs.rs index 099242f59..35419354b 100644 --- a/src/agent/onefuzz/src/fs.rs +++ b/src/agent/onefuzz/src/fs.rs @@ -74,9 +74,11 @@ pub async fn set_executable(path: impl AsRef) -> Result<()> { .stdin(Stdio::null()) .stdout(Stdio::null()) .stderr(Stdio::piped()) - .spawn()? + .spawn() + .with_context(|| format!("command failed to start: chmod -R +x {}", path.display()))? .wait_with_output() - .await?; + .await + .with_context(|| format!("command failed to run: chmod -R +x {}", path.display()))?; if !output.status.success() { bail!("'chmod -R +x' of {:?} failed: {}", path, output.status); diff --git a/src/agent/onefuzz/src/libfuzzer.rs b/src/agent/onefuzz/src/libfuzzer.rs index 7ff117258..16552dc4c 100644 --- a/src/agent/onefuzz/src/libfuzzer.rs +++ b/src/agent/onefuzz/src/libfuzzer.rs @@ -5,7 +5,7 @@ use crate::{ expand::Expand, input_tester::{TestResult, Tester}, }; -use anyhow::Result; +use anyhow::{Context, Result}; use std::{ collections::HashMap, ffi::OsString, @@ -71,7 +71,12 @@ impl<'a> LibFuzzer<'a> { cmd.arg(o); } - let result = cmd.spawn()?.wait_with_output().await?; + let result = cmd + .spawn() + .with_context(|| format_err!("libfuzzer failed to start: {}", self.exe.display()))? + .wait_with_output() + .await + .with_context(|| format_err!("libfuzzer failed to run: {}", self.exe.display()))?; if !result.status.success() { bail!("fuzzer does not respond to '-help=1'. output:{:?}", result); } @@ -141,7 +146,9 @@ impl<'a> LibFuzzer<'a> { cmd.arg(dir.as_ref()); } - let child = cmd.spawn()?; + let child = cmd + .spawn() + .with_context(|| format_err!("libfuzzer failed to start: {}", self.exe.display()))?; Ok(child) } @@ -204,7 +211,12 @@ impl<'a> LibFuzzer<'a> { cmd.arg(o); } - let output = cmd.spawn()?.wait_with_output().await?; + let output = cmd + .spawn() + .with_context(|| format_err!("libfuzzer failed to start: {}", self.exe.display()))? + .wait_with_output() + .await + .with_context(|| format_err!("libfuzzer failed to run: {}", self.exe.display()))?; let output_text = String::from_utf8_lossy(&output.stderr); let pat = r"MERGE-OUTER: (\d+) new files with (\d+) new features added"; diff --git a/src/agent/onefuzz/src/process.rs b/src/agent/onefuzz/src/process.rs index 9360ac18d..1dc3baf98 100644 --- a/src/agent/onefuzz/src/process.rs +++ b/src/agent/onefuzz/src/process.rs @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -use anyhow::Result; +use anyhow::{Context, Result}; use process_control::{self, ChildExt, Timeout}; use std::path::Path; use std::process::Command; @@ -122,8 +122,13 @@ pub async fn run_cmd( .args(argv) .envs(env); + // make a stringified version to save in the context of spawn_blocking + let program_name = program.display().to_string(); + let runner = tokio::task::spawn_blocking(move || { - let child = cmd.spawn()?; + let child = cmd + .spawn() + .with_context(|| format!("process failed to start: {}", program_name))?; child .with_output_timeout(timeout) .terminating()