@@ -4,10 +4,12 @@ use crate::prelude::*;
44use crate :: runner:: helpers:: ignored_objects_path:: get_objects_path_to_ignore;
55use crate :: runner:: helpers:: introspected_node:: setup_introspected_node;
66use lazy_static:: lazy_static;
7- use std:: env;
87use std:: fs:: canonicalize;
8+ use std:: io:: { Read , Write } ;
99use std:: path:: Path ;
10+ use std:: process:: ExitStatus ;
1011use std:: { collections:: HashMap , env:: consts:: ARCH , process:: Command } ;
12+ use std:: { env, thread} ;
1113
1214lazy_static ! {
1315 static ref BASE_INJECTED_ENV : HashMap <& ' static str , String > = {
@@ -54,6 +56,43 @@ fn get_bench_command(config: &Config) -> String {
5456 . replace ( "cargo codspeed" , "cargo-codspeed" )
5557}
5658
59+ pub const VALGRIND_EXECUTION_TARGET : & str = "valgrind::execution" ;
60+
61+ fn run_command_with_log_pipe ( mut cmd : Command ) -> Result < ExitStatus > {
62+ fn log_tee (
63+ mut reader : impl Read ,
64+ mut writer : impl Write ,
65+ log_prefix : Option < & str > ,
66+ ) -> Result < ( ) > {
67+ let prefix = log_prefix. unwrap_or ( "" ) ;
68+ let mut buffer = [ 0 ; 1024 ] ;
69+ loop {
70+ let bytes_read = reader. read ( & mut buffer) ?;
71+ if bytes_read == 0 {
72+ break ;
73+ }
74+ writer. write_all ( & buffer[ ..bytes_read] ) ?;
75+ trace ! ( target: VALGRIND_EXECUTION_TARGET , "{}{}" , prefix, String :: from_utf8_lossy( & buffer[ ..bytes_read] ) ) ;
76+ }
77+ Ok ( ( ) )
78+ }
79+
80+ let mut process = cmd
81+ . stdout ( std:: process:: Stdio :: piped ( ) )
82+ . stderr ( std:: process:: Stdio :: piped ( ) )
83+ . spawn ( )
84+ . context ( "failed to spawn the process" ) ?;
85+ let stdout = process. stdout . take ( ) . expect ( "unable to get stdout" ) ;
86+ let stderr = process. stderr . take ( ) . expect ( "unable to get stderr" ) ;
87+ thread:: spawn ( move || {
88+ log_tee ( stdout, std:: io:: stdout ( ) , None ) . unwrap ( ) ;
89+ } ) ;
90+ thread:: spawn ( move || {
91+ log_tee ( stderr, std:: io:: stderr ( ) , Some ( "[stderr]" ) ) . unwrap ( ) ;
92+ } ) ;
93+ process. wait ( ) . context ( "failed to wait for the process" )
94+ }
95+
5796pub fn measure (
5897 config : & Config ,
5998 profile_folder : & Path ,
@@ -102,8 +141,7 @@ pub fn measure(
102141 }
103142
104143 debug ! ( "cmd: {:?}" , cmd) ;
105- let status = cmd
106- . status ( )
144+ let status = run_command_with_log_pipe ( cmd)
107145 . map_err ( |e| anyhow ! ( "failed to execute the benchmark process. {}" , e) ) ?;
108146 if !status. success ( ) {
109147 bail ! ( "failed to execute the benchmark process" ) ;
0 commit comments