diff --git a/src/run/runner/wall_time/executor.rs b/src/run/runner/wall_time/executor.rs index ff524759..f26334d0 100644 --- a/src/run/runner/wall_time/executor.rs +++ b/src/run/runner/wall_time/executor.rs @@ -191,7 +191,8 @@ impl Executor for WallTimeExecutor { if let Some(perf) = &self.perf && config.enable_perf { - perf.run(cmd_builder, config).await + perf.run(cmd_builder, config, &run_data.profile_folder) + .await } else { let cmd = wrap_with_sudo(cmd_builder)?.build(); debug!("cmd: {cmd:?}"); diff --git a/src/run/runner/wall_time/perf/mod.rs b/src/run/runner/wall_time/perf/mod.rs index 17d0cfb1..0799b9f4 100644 --- a/src/run/runner/wall_time/perf/mod.rs +++ b/src/run/runner/wall_time/perf/mod.rs @@ -26,7 +26,7 @@ use runner_shared::fifo::MarkerType; use runner_shared::metadata::PerfMetadata; use runner_shared::unwind_data::UnwindData; use std::collections::HashSet; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::time::Duration; use std::{cell::OnceCell, collections::HashMap, process::ExitStatus}; @@ -41,7 +41,7 @@ pub mod perf_map; pub mod unwind_data; const PERF_METADATA_CURRENT_VERSION: u64 = 1; -const PERF_DATA_PATH: &str = "/tmp/perf.data"; +const PERF_DATA_FILE_NAME: &str = "perf.pipedata"; pub struct PerfRunner { benchmark_data: OnceCell, @@ -89,6 +89,7 @@ impl PerfRunner { &self, mut cmd_builder: CommandBuilder, config: &Config, + profile_folder: &Path, ) -> anyhow::Result { let perf_fifo = PerfFifo::new()?; let runner_fifo = RunnerFifo::new()?; @@ -139,12 +140,24 @@ impl PerfRunner { perf_fifo.ctl_fifo_path.to_string_lossy(), perf_fifo.ack_fifo_path.to_string_lossy() ), - &format!("--output={PERF_DATA_PATH}"), + "-o", + "-", // forces pipe mode "--", ]); cmd_builder.wrap_with(perf_wrapper_builder); - let cmd = wrap_with_sudo(cmd_builder)?.build(); - debug!("cmd: {cmd:?}"); + + // Copy the perf data to the profile folder + let perf_data_file_path = profile_folder.join(PERF_DATA_FILE_NAME); + + let raw_command = format!( + "{} | cat > {}", + &cmd_builder.as_command_line(), + perf_data_file_path.to_string_lossy() + ); + let mut wrapped_builder = CommandBuilder::new("sh"); + wrapped_builder.args(["-c", &raw_command]); + let cmd = wrap_with_sudo(wrapped_builder)?.build(); + println!("cmd: {cmd:?}"); let on_process_started = async |_| -> anyhow::Result<()> { let data = Self::handle_fifo(runner_fifo, perf_fifo).await?; @@ -156,28 +169,9 @@ impl PerfRunner { run_command_with_log_pipe_and_callback(cmd, on_process_started).await } - pub async fn save_files_to(&self, profile_folder: &PathBuf) -> anyhow::Result<()> { + pub async fn save_files_to(&self, profile_folder: &Path) -> anyhow::Result<()> { let start = std::time::Instant::now(); - // We ran perf with sudo, so we have to change the ownership of the perf.data - run_with_sudo( - "chown", - [ - "-R", - &format!( - "{}:{}", - nix::unistd::Uid::current(), - nix::unistd::Gid::current() - ), - PERF_DATA_PATH, - ], - )?; - - // Copy the perf data to the profile folder - let perf_data_dest = profile_folder.join("perf.data"); - std::fs::copy(PERF_DATA_PATH, &perf_data_dest) - .with_context(|| format!("Failed to copy perf data to {perf_data_dest:?}",))?; - let bench_data = self .benchmark_data .get()