File tree Expand file tree Collapse file tree
src/run/runner/wall_time/perf Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -9,6 +9,7 @@ use crate::run::runner::helpers::run_with_sudo::run_with_sudo;
99use crate :: run:: runner:: valgrind:: helpers:: ignored_objects_path:: get_objects_path_to_ignore;
1010use crate :: run:: runner:: valgrind:: helpers:: perf_maps:: harvest_perf_maps_for_pids;
1111use crate :: run:: runner:: wall_time:: perf:: jit_dump:: harvest_perf_jit_for_pids;
12+ use crate :: run:: runner:: wall_time:: perf:: perf_executable:: get_working_perf_executable;
1213use crate :: run:: runner:: wall_time:: perf:: unwind_data:: UnwindDataExt ;
1314use anyhow:: Context ;
1415use fifo:: { PerfFifo , RunnerFifo } ;
@@ -31,6 +32,7 @@ mod setup;
3132
3233pub mod elf_helper;
3334pub mod fifo;
35+ pub mod perf_executable;
3436pub mod perf_map;
3537pub mod unwind_data;
3638
@@ -118,8 +120,11 @@ impl PerfRunner {
118120 ""
119121 } ;
120122
123+ let perf_executable =
124+ get_working_perf_executable ( ) . context ( "Failed to find a working perf executable" ) ?;
125+
121126 let perf_args = [
122- "perf" ,
127+ perf_executable . as_str ( ) ,
123128 "record" ,
124129 quiet_flag,
125130 "--timestamp" ,
Original file line number Diff line number Diff line change 1+ use crate :: prelude:: * ;
2+
3+ use std:: process:: Command ;
4+
5+ const FIND_PERF_CMD : & str =
6+ "find /usr/lib -executable -path \" /usr/lib/linux-tools-*/perf\" | sort | tail -n1" ;
7+
8+ /// Attempts to find the path to the `perf` executable that is installed and working.
9+ /// Returns None if `perf` is not installed or not functioning correctly.
10+ pub fn get_working_perf_executable ( ) -> Option < String > {
11+ let is_installed = Command :: new ( "which" )
12+ . arg ( "perf" )
13+ . output ( )
14+ . is_ok_and ( |output| output. status . success ( ) ) ;
15+ if !is_installed {
16+ debug ! ( "perf is not installed" ) ;
17+ return None ;
18+ }
19+
20+ debug ! ( "perf is installed, checking if it is functioning correctly" ) ;
21+ if Command :: new ( "perf" )
22+ . arg ( "--version" ) // here we use --version to check if perf is working
23+ . output ( )
24+ . is_ok_and ( |output| output. status . success ( ) )
25+ {
26+ return Some ( "perf" . to_string ( ) ) ;
27+ } else {
28+ // The following is a workaround for this outstanding Ubuntu issue: https://bugs.launchpad.net/ubuntu/+source/linux-hwe-6.14/+bug/2117159/
29+ debug ! (
30+ "perf command is not functioning correctly, trying to find alternative path using \" {FIND_PERF_CMD}\" "
31+ ) ;
32+ if let Ok ( perf_path) = Command :: new ( "sh" ) . arg ( "-c" ) . arg ( FIND_PERF_CMD ) . output ( ) {
33+ if perf_path. status . success ( ) {
34+ let path = String :: from_utf8_lossy ( & perf_path. stdout ) ;
35+ debug ! ( "Found perf path on retry: {}" , path. trim( ) ) ;
36+ return Some ( path. trim ( ) . to_string ( ) ) ;
37+ }
38+ }
39+ }
40+
41+ debug ! ( "perf is installed but not functioning correctly" ) ;
42+ None
43+ }
Original file line number Diff line number Diff line change 11use crate :: run:: runner:: helpers:: apt;
2+ use crate :: run:: runner:: wall_time:: perf:: perf_executable:: get_working_perf_executable;
23use crate :: { prelude:: * , run:: check_system:: SystemInfo } ;
34
45use std:: { path:: Path , process:: Command } ;
56
67fn is_perf_installed ( ) -> bool {
7- let is_installed = Command :: new ( "which" )
8- . arg ( "perf" )
9- . output ( )
10- . is_ok_and ( |output| output . status . success ( ) ) ;
11- if !is_installed {
12- debug ! ( "perf is not installed" ) ;
13- return false ;
14- }
15-
16- if let Ok ( version_output ) = Command :: new ( "perf" ) . arg ( "--version" ) . output ( ) {
17- if !version_output . status . success ( ) {
18- debug ! (
19- "Failed to get perf version. stderr : {}",
20- String :: from_utf8_lossy ( & version_output . stderr )
21- ) ;
22- return false ;
8+ if let Some ( perf_path ) = get_working_perf_executable ( ) {
9+ if let Ok ( version_output ) = Command :: new ( perf_path ) . arg ( "--version" ) . output ( ) {
10+ if !version_output . status . success ( ) {
11+ debug ! (
12+ "Failed to get perf version. stderr: {}" ,
13+ String :: from_utf8_lossy ( & version_output . stderr )
14+ ) ;
15+
16+ return false ;
17+ }
18+
19+ let version = String :: from_utf8_lossy ( & version_output . stdout ) ;
20+ debug ! ( "Found perf version: {}", version . trim ( ) ) ;
21+ true
22+ } else {
23+ false
2324 }
24-
25- let version = String :: from_utf8_lossy ( & version_output. stdout ) ;
26- debug ! ( "Found perf version: {}" , version. trim( ) ) ;
27- true
2825 } else {
2926 false
3027 }
You can’t perform that action at this time.
0 commit comments