Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Terminate process on timeout in windows for the coverage task #3529

Merged
merged 7 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/agent/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/agent/coverage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ symbolic = { version = "12.3", features = [
"symcache",
] }
thiserror = "1.0"
process_control = "4.0"

[target.'cfg(target_os = "windows")'.dependencies]
debugger = { path = "../debugger" }
Expand Down
60 changes: 38 additions & 22 deletions src/agent/coverage/src/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,31 +121,34 @@
#[cfg(target_os = "windows")]
pub fn record(self) -> Result<Recorded> {
use debugger::Debugger;
use process_control::{ChildExt, Control};
use windows::WindowsRecorder;

let loader = self.loader.clone();
let mut recorder =
WindowsRecorder::new(&loader, self.module_allowlist, self.cache.as_ref());
let (mut dbg, child) = Debugger::init(self.cmd, &mut recorder)?;
dbg.run(&mut recorder)?;
tevoinea marked this conversation as resolved.
Show resolved Hide resolved

Check failure on line 132 in src/agent/coverage/src/record.rs

View workflow job for this annotation

GitHub Actions / agent (self-hosted, 1ES.Pool=onefuzz-ci, 1ES.ImageOverride=github-runner-image-ubuntu-20.04)

Diff in /usr/local/vss-agent/2.309.0/_work/onefuzz/onefuzz/src/agent/coverage/src/record.rs
// If the debugger callbacks fail, this may return with a spurious clean exit.
let output = child
.controlled_with_output()
.time_limit(self.timeout)
.terminate_for_timeout()
.wait()?
.ok_or_else(|| crate::timer::TimerError::Timeout(self.timeout))?.into();

// Check if debugging was stopped due to a callback error.
//
// If so, the debugger terminated the target, and the recorded coverage and
// output are both invalid.
if let Some(err) = recorder.stop_error {
return Err(err);
}

crate::timer::timed(self.timeout, move || {
let mut recorder =
WindowsRecorder::new(&loader, self.module_allowlist, self.cache.as_ref());
let (mut dbg, child) = Debugger::init(self.cmd, &mut recorder)?;
dbg.run(&mut recorder)?;

// If the debugger callbacks fail, this may return with a spurious clean exit.
let output = child.wait_with_output()?.into();

// Check if debugging was stopped due to a callback error.
//
// If so, the debugger terminated the target, and the recorded coverage and
// output are both invalid.
if let Some(err) = recorder.stop_error {
return Err(err);
}

let coverage = recorder.coverage;
let coverage = recorder.coverage;

Ok(Recorded { coverage, output })
})?
Ok(Recorded { coverage, output })
}
}

Expand All @@ -157,19 +160,32 @@

#[derive(Clone, Debug, Default)]
pub struct Output {
pub status: Option<ExitStatus>,
pub status: Option<process_control::ExitStatus>,
pub stderr: String,
pub stdout: String,
}

impl From<process_control::Output> for Output {
fn from(output: process_control::Output) -> Self {
let status = Some(output.status);
let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();
Self {
status,
stdout,
stderr,
}
}
}

impl From<std::process::Output> for Output {
fn from(output: std::process::Output) -> Self {
let status = Some(output.status);
let stdout = String::from_utf8_lossy(&output.stdout).into_owned();
let stderr = String::from_utf8_lossy(&output.stderr).into_owned();

Self {
status,
status: status.map(Into::into),
stdout,
stderr,
}
Expand Down
Loading