add context to command failures (#466)

Fixes #465
This commit is contained in:
bmc-msft
2021-01-26 16:29:59 -05:00
committed by GitHub
parent de67c9db63
commit cfcf493a23
10 changed files with 78 additions and 32 deletions

View File

@ -238,7 +238,10 @@ impl Debugger {
mut command: Command, mut command: Command,
callbacks: &mut impl DebugEventHandler, callbacks: &mut impl DebugEventHandler,
) -> Result<(Self, Child)> { ) -> 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) }) check_winapi(|| unsafe { DebugSetProcessKillOnExit(TRUE) })
.context("Setting DebugSetProcessKillOnExit to TRUE")?; .context("Setting DebugSetProcessKillOnExit to TRUE")?;

View File

@ -126,7 +126,7 @@ impl CoverageRecorder {
cmd.env(k, v); cmd.env(k, v);
} }
let child = cmd.spawn()?; let child = cmd.spawn().context("gdb failed to start")?;
Ok(child) Ok(child)
} }
@ -163,7 +163,7 @@ impl CoverageRecorder {
cmd.env(k, v); cmd.env(k, v);
} }
let child = cmd.spawn()?; let child = cmd.spawn().context("cdb.exe failed to start")?;
Ok(child) Ok(child)
} }

View File

@ -6,7 +6,7 @@ use crate::tasks::{
heartbeat::*, heartbeat::*,
utils::{self, default_bool_true}, utils::{self, default_bool_true},
}; };
use anyhow::Result; use anyhow::{Context, Result};
use futures::stream::StreamExt; use futures::stream::StreamExt;
use onefuzz::{ use onefuzz::{
expand::Expand, expand::Expand,
@ -150,7 +150,7 @@ impl GeneratorTask {
output_dir: impl AsRef<Path>, output_dir: impl AsRef<Path>,
) -> Result<()> { ) -> Result<()> {
utils::reset_tmp_dir(&output_dir).await?; utils::reset_tmp_dir(&output_dir).await?;
let mut generator = { let (mut generator, generator_path) = {
let mut expand = Expand::new(); let mut expand = Expand::new();
expand expand
.generated_inputs(&output_dir) .generated_inputs(&output_dir)
@ -179,11 +179,13 @@ impl GeneratorTask {
for (k, v) in &self.config.generator_env { for (k, v) in &self.config.generator_env {
generator.env(k, expand.evaluate_value(v)?); generator.env(k, expand.evaluate_value(v)?);
} }
generator (generator, generator_path)
}; };
info!("Generating test cases with {:?}", generator); 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?; monitor_process(output, "generator".to_string(), true, None).await?;
Ok(()) Ok(())

View File

@ -9,7 +9,7 @@ use crate::tasks::{
stats::common::{monitor_stats, StatsFormat}, stats::common::{monitor_stats, StatsFormat},
utils::CheckNotify, utils::CheckNotify,
}; };
use anyhow::{Error, Result}; use anyhow::{Context, Error, Result};
use onefuzz::{ use onefuzz::{
expand::Expand, expand::Expand,
fs::{has_files, set_executable, OwnedDir}, fs::{has_files, set_executable, OwnedDir},
@ -213,7 +213,9 @@ async fn start_supervisor(
} }
info!("starting supervisor '{:?}'", cmd); info!("starting supervisor '{:?}'", cmd);
let child = cmd.spawn()?; let child = cmd
.spawn()
.with_context(|| format!("supervisor failed to start: {:?}", cmd))?;
Ok(child) Ok(child)
} }

View File

@ -2,7 +2,7 @@
// Licensed under the MIT License. // Licensed under the MIT License.
use crate::auth::Secret; use crate::auth::Secret;
use anyhow::Result; use anyhow::{Context, Result};
use onefuzz::machine_id::get_scaleset_name; use onefuzz::machine_id::get_scaleset_name;
use std::process::Stdio; use std::process::Stdio;
use tokio::{fs, io::AsyncWriteExt, process::Command}; use tokio::{fs, io::AsyncWriteExt, process::Command};
@ -52,9 +52,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> {
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn()? .spawn()
.context("icacls failed to start")?
.wait_with_output() .wait_with_output()
.await?; .await
.context("icalcs failed to run")?;
if !result.status.success() { if !result.status.success() {
bail!( bail!(
"set authorized_keys ({}) permissions failed: {:?}", "set authorized_keys ({}) permissions failed: {:?}",
@ -70,9 +72,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> {
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn()? .spawn()
.context("icacls failed to start")?
.wait_with_output() .wait_with_output()
.await?; .await
.context("icacls failed to run")?;
if !result.status.success() { if !result.status.success() {
bail!( bail!(
"set authorized_keys ({}) permissions failed: {:?}", "set authorized_keys ({}) permissions failed: {:?}",
@ -92,9 +96,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> {
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn()? .spawn()
.context("Powershell Get-ACL | Set-ACL failed to start")?
.wait_with_output() .wait_with_output()
.await?; .await
.context("Powershell Get-ACL | Set-ACL failed to run")?;
if !result.status.success() { if !result.status.success() {
bail!( bail!(
"set authorized_keys ({}) permissions failed: {:?}", "set authorized_keys ({}) permissions failed: {:?}",
@ -137,9 +143,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> {
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn()? .spawn()
.context("chmod failed to start")?
.wait_with_output() .wait_with_output()
.await?; .await
.context("chmod failed to run")?;
if !result.status.success() { if !result.status.success() {
bail!("set $HOME/.ssh permissions failed: {:?}", result); bail!("set $HOME/.ssh permissions failed: {:?}", result);
} }
@ -159,9 +167,11 @@ pub async fn add_ssh_key(key_info: SshKeyInfo) -> Result<()> {
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn()? .spawn()
.context("chmod failed to start")?
.wait_with_output() .wait_with_output()
.await?; .await
.context("chmod failed to run")?;
if !result.status.success() { if !result.status.success() {
bail!( bail!(
"set authorized_keys ({}) permissions failed: {:?}", "set authorized_keys ({}) permissions failed: {:?}",

View File

@ -231,7 +231,7 @@ impl IWorkerRunner for WorkerRunner {
cmd.stderr(Stdio::piped()); cmd.stderr(Stdio::piped());
cmd.stdout(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); let child = Box::new(child);
Ok(child) Ok(child)

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. // Copyright (c) Microsoft Corporation.
// Licensed under the MIT License. // Licensed under the MIT License.
use anyhow::Result; use anyhow::{Context, Result};
use std::ffi::OsStr; use std::ffi::OsStr;
use tokio::process::Command; use tokio::process::Command;
@ -21,7 +21,12 @@ pub async fn sync(src: impl AsRef<OsStr>, dst: impl AsRef<OsStr>, delete_dst: bo
cmd.arg("--delete-destination"); 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() { if !output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout); let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr); let stderr = String::from_utf8_lossy(&output.stderr);
@ -53,7 +58,12 @@ pub async fn copy(src: impl AsRef<OsStr>, dst: impl AsRef<OsStr>, recursive: boo
cmd.arg("--recursive=true"); 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() { if !output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout); let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr); let stderr = String::from_utf8_lossy(&output.stderr);

View File

@ -74,9 +74,11 @@ pub async fn set_executable(path: impl AsRef<Path>) -> Result<()> {
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::null()) .stdout(Stdio::null())
.stderr(Stdio::piped()) .stderr(Stdio::piped())
.spawn()? .spawn()
.with_context(|| format!("command failed to start: chmod -R +x {}", path.display()))?
.wait_with_output() .wait_with_output()
.await?; .await
.with_context(|| format!("command failed to run: chmod -R +x {}", path.display()))?;
if !output.status.success() { if !output.status.success() {
bail!("'chmod -R +x' of {:?} failed: {}", path, output.status); bail!("'chmod -R +x' of {:?} failed: {}", path, output.status);

View File

@ -5,7 +5,7 @@ use crate::{
expand::Expand, expand::Expand,
input_tester::{TestResult, Tester}, input_tester::{TestResult, Tester},
}; };
use anyhow::Result; use anyhow::{Context, Result};
use std::{ use std::{
collections::HashMap, collections::HashMap,
ffi::OsString, ffi::OsString,
@ -71,7 +71,12 @@ impl<'a> LibFuzzer<'a> {
cmd.arg(o); 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() { if !result.status.success() {
bail!("fuzzer does not respond to '-help=1'. output:{:?}", result); bail!("fuzzer does not respond to '-help=1'. output:{:?}", result);
} }
@ -141,7 +146,9 @@ impl<'a> LibFuzzer<'a> {
cmd.arg(dir.as_ref()); 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) Ok(child)
} }
@ -204,7 +211,12 @@ impl<'a> LibFuzzer<'a> {
cmd.arg(o); 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 output_text = String::from_utf8_lossy(&output.stderr);
let pat = r"MERGE-OUTER: (\d+) new files with (\d+) new features added"; let pat = r"MERGE-OUTER: (\d+) new files with (\d+) new features added";

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. // Copyright (c) Microsoft Corporation.
// Licensed under the MIT License. // Licensed under the MIT License.
use anyhow::Result; use anyhow::{Context, Result};
use process_control::{self, ChildExt, Timeout}; use process_control::{self, ChildExt, Timeout};
use std::path::Path; use std::path::Path;
use std::process::Command; use std::process::Command;
@ -122,8 +122,13 @@ pub async fn run_cmd<S: ::std::hash::BuildHasher>(
.args(argv) .args(argv)
.envs(env); .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 runner = tokio::task::spawn_blocking(move || {
let child = cmd.spawn()?; let child = cmd
.spawn()
.with_context(|| format!("process failed to start: {}", program_name))?;
child child
.with_output_timeout(timeout) .with_output_timeout(timeout)
.terminating() .terminating()