@@ -34,7 +34,11 @@ impl WallTimeExecutor {
3434 . into_iter ( )
3535 . map ( |( k, v) | ( k. into ( ) , v) ) ,
3636 )
37- . map ( |( env, value) | format ! ( "{env}={value}" ) )
37+ . map ( |( env, value) | {
38+ // Properly quote the value to handle special characters
39+ let escaped_value = value. replace ( "\\ " , "\\ \\ " ) . replace ( "\" " , "\\ \" " ) ;
40+ format ! ( "export {env}=\" {escaped_value}\" " )
41+ } )
3842 . collect :: < Vec < _ > > ( )
3943 . join ( "\n " ) ;
4044
@@ -49,8 +53,15 @@ impl WallTimeExecutor {
4953
5054 let uid = nix:: unistd:: Uid :: current ( ) . as_raw ( ) ;
5155 let gid = nix:: unistd:: Gid :: current ( ) . as_raw ( ) ;
56+
57+ // Remarks:
58+ // - We're using --scope so that perf is able to capture the events of the benchmark process.
59+ // - We can't user `--user` here because we need to run in `codspeed.slice`, otherwise we'd run in
60+ // user.slice` (which is isolated). We can use `--gid` and `--uid` to run the command as the current user.
61+ // - We must use `bash` here instead of `sh` since `source` isn't available when symlinked to `dash`.
62+ // - We have to pass the environment variables because `--scope` only inherits the system and not the user environment variables.
5263 let cmd = format ! (
53- "systemd-run {quiet_flag} --pipe --collect --wait -- slice=codspeed.slice --same-dir --uid={uid} --gid={gid} --property=EnvironmentFile={} -- sh -c '{}'" ,
64+ "systemd-run {quiet_flag} --scope --slice=codspeed.slice --same-dir --uid={uid} --gid={gid} -- bash -c 'source {} && {}'" ,
5465 env_file. path( ) . display( ) ,
5566 bench_cmd. replace( "'" , "\" " )
5667 ) ;
0 commit comments