Skip to content

Commit 74043ce

Browse files
committed
feat(runner): improve error handling for valgrind
Signed-off-by: not-matthias <matthias@codspeed.io>
1 parent d6b498f commit 74043ce

1 file changed

Lines changed: 36 additions & 2 deletions

File tree

src/run/runner/valgrind/measure.rs

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::run::{config::Config, instruments::mongo_tracer::MongoTracer};
99
use lazy_static::lazy_static;
1010
use std::env;
1111
use std::fs::canonicalize;
12+
use std::io::Read;
1213
use std::path::Path;
1314
use std::{env::consts::ARCH, process::Command};
1415

@@ -85,8 +86,18 @@ pub fn measure(
8586
.arg(format!("--callgrind-out-file={}", profile_path.to_str().unwrap()).as_str())
8687
.arg(format!("--log-file={}", log_path.to_str().unwrap()).as_str());
8788

88-
// Set the command to execute
89-
cmd.args(["sh", "-c", get_bench_command(config)?.as_str()]);
89+
// The command is wrapped in a shell script, which executes it in a
90+
// subprocess and then writes the exit code to a file. The process will
91+
// always exit with status code 0, unless valgrind fails.
92+
let mut cmd_status_file = tempfile::NamedTempFile::new()?;
93+
let run_cmd = format!(
94+
"(eval \"{}\"); echo \"$?\" > \"{}\"",
95+
get_bench_command(config)?,
96+
cmd_status_file.path().display()
97+
);
98+
99+
// Set the command to execute:
100+
cmd.args(["sh", "-c", run_cmd.as_str()]);
90101

91102
// TODO: refactor and move this to the `Instruments` struct
92103
if let Some(mongo_tracer) = mongo_tracer {
@@ -96,7 +107,30 @@ pub fn measure(
96107
debug!("cmd: {:?}", cmd);
97108
let status = run_command_with_log_pipe(cmd)
98109
.map_err(|e| anyhow!("failed to execute the benchmark process. {}", e))?;
110+
let cmd_status = {
111+
let mut content = String::new();
112+
cmd_status_file.read_to_string(&mut content)?;
113+
114+
content.parse::<u32>().unwrap_or(1)
115+
};
116+
117+
debug!(
118+
"Valgrind exit code = {:?}, Program exit code = {}",
119+
status.code(),
120+
cmd_status
121+
);
122+
123+
// Check the valgrind exit code
99124
if !status.success() {
125+
let valgrind_log = profile_folder.join("valgrind.log");
126+
let valgrind_log = std::fs::read_to_string(&valgrind_log).unwrap_or_default();
127+
debug!("valgrind.log: {}", valgrind_log);
128+
129+
bail!("failed to execute valgrind");
130+
}
131+
132+
// Check the exit code which was written to the file by the wrapper script.
133+
if cmd_status != 0 {
100134
bail!("failed to execute the benchmark process");
101135
}
102136

0 commit comments

Comments
 (0)