@@ -9,6 +9,7 @@ use crate::run::{config::Config, instruments::mongo_tracer::MongoTracer};
99use lazy_static:: lazy_static;
1010use std:: env;
1111use std:: fs:: canonicalize;
12+ use std:: io:: Read ;
1213use std:: path:: Path ;
1314use 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