(
&mut self,
mut cmd_builder: CommandBuilder,
config: &ExecutorConfig,
profile_folder: &Path,
isolate: bool,
)
| 87 | } |
| 88 | |
| 89 | async fn wrap_command( |
| 90 | &mut self, |
| 91 | mut cmd_builder: CommandBuilder, |
| 92 | config: &ExecutorConfig, |
| 93 | profile_folder: &Path, |
| 94 | isolate: bool, |
| 95 | ) -> anyhow::Result<CommandBuilder> { |
| 96 | let perf_fifo = PerfFifo::new()?; |
| 97 | let perf_file_path = profile_folder.join(PERF_PIPEDATA_FILE_NAME); |
| 98 | |
| 99 | // Infer the unwinding mode from the benchmark cmd |
| 100 | let (cg_mode, stack_size) = if let Some(mode) = config.perf_unwinding_mode { |
| 101 | (mode, None) |
| 102 | } else if command_has_executable( |
| 103 | &config.command, |
| 104 | &["gradle", "gradlew", "java", "maven", "mvn", "mvnw"], |
| 105 | ) { |
| 106 | // In Java, we must use FP unwinding otherwise we'll have broken call stacks. |
| 107 | (UnwindingMode::FramePointer, None) |
| 108 | } else if command_has_executable(&config.command, &["cargo"]) { |
| 109 | (UnwindingMode::Dwarf, None) |
| 110 | } else if command_has_executable(&config.command, &["go"]) { |
| 111 | (UnwindingMode::FramePointer, None) |
| 112 | } else if command_has_executable(&config.command, &["pytest", "uv", "python", "python3"]) { |
| 113 | // Note that the higher the stack size, the larger the file, although it is mitigated |
| 114 | // by zstd compression |
| 115 | (UnwindingMode::Dwarf, Some(32 * 1024)) |
| 116 | } else { |
| 117 | // Default to dwarf unwinding since it works well with most binaries. |
| 118 | debug!("No call graph mode detected, defaulting to dwarf"); |
| 119 | (UnwindingMode::Dwarf, None) |
| 120 | }; |
| 121 | |
| 122 | let cg_mode = match cg_mode { |
| 123 | UnwindingMode::FramePointer => { |
| 124 | suppress_go_perf_unwinding_warning(); |
| 125 | "fp" |
| 126 | } |
| 127 | UnwindingMode::Dwarf => &format!("dwarf,{}", stack_size.unwrap_or(8192)), |
| 128 | }; |
| 129 | debug!("Using call graph mode: {cg_mode:?}"); |
| 130 | |
| 131 | let working_perf_executable = |
| 132 | get_working_perf_executable().context("Failed to find a working perf executable")?; |
| 133 | let mut perf_wrapper_builder = CommandBuilder::new(&working_perf_executable); |
| 134 | perf_wrapper_builder.arg("record"); |
| 135 | if !is_codspeed_debug_enabled() { |
| 136 | perf_wrapper_builder.arg("--quiet"); |
| 137 | } |
| 138 | // Add compression if available |
| 139 | if let Some(compression_flags) = get_compression_flags(&working_perf_executable)? { |
| 140 | perf_wrapper_builder.arg(compression_flags); |
| 141 | // Add events flag if all required events are available |
| 142 | if let Some(events_flag) = get_event_flags(&working_perf_executable)? { |
| 143 | perf_wrapper_builder.arg(events_flag); |
| 144 | } |
| 145 | } |
| 146 |
no test coverage detected