1- use std:: io:: Error ;
1+ use std:: io;
22use std:: mem;
33use std:: time:: Duration ;
44
@@ -9,6 +9,7 @@ use clap::Parser;
99
1010use libbpf_rs:: skel:: OpenSkel as _;
1111use libbpf_rs:: skel:: SkelBuilder as _;
12+ use libbpf_rs:: ErrorExt as _;
1213
1314use nix:: unistd:: close;
1415
@@ -40,7 +41,7 @@ struct stacktrace_event {
4041 ustack : [ u64 ; MAX_STACK_DEPTH ] ,
4142}
4243
43- fn init_perf_monitor ( freq : u64 ) -> Vec < i32 > {
44+ fn init_perf_monitor ( freq : u64 ) -> Result < Vec < i32 > , libbpf_rs :: Error > {
4445 let nprocs = libbpf_rs:: num_possible_cpus ( ) . unwrap ( ) ;
4546 let pid = -1 ;
4647 let buf: Vec < u8 > = vec ! [ 0 ; mem:: size_of:: <syscall:: perf_event_attr>( ) ] ;
@@ -56,8 +57,13 @@ fn init_perf_monitor(freq: u64) -> Vec<i32> {
5657 attr. flags = 1 << 10 ; // freq = 1
5758 ( 0 ..nprocs)
5859 . map ( |cpu| {
59- let fd = syscall:: perf_event_open ( attr. as_ref ( ) , pid, cpu as i32 , -1 , 0 ) ;
60- fd as i32
60+ let fd = syscall:: perf_event_open ( attr. as_ref ( ) , pid, cpu as i32 , -1 , 0 ) as i32 ;
61+ if fd == -1 {
62+ Err ( libbpf_rs:: Error :: from ( io:: Error :: last_os_error ( ) ) )
63+ . context ( "failed to open perf event" )
64+ } else {
65+ Ok ( fd)
66+ }
6167 } )
6268 . collect ( )
6369}
@@ -72,7 +78,11 @@ fn attach_perf_event(
7278 . collect ( )
7379}
7480
75- fn print_frame ( name : & str , addr_info : Option < ( blazesym:: Addr , blazesym:: Addr , usize ) > , code_info : & Option < symbolize:: CodeInfo > ) {
81+ fn print_frame (
82+ name : & str ,
83+ addr_info : Option < ( blazesym:: Addr , blazesym:: Addr , usize ) > ,
84+ code_info : & Option < symbolize:: CodeInfo > ,
85+ ) {
7686 let code_info = code_info. as_ref ( ) . map ( |code_info| {
7787 let path = code_info. to_path ( ) ;
7888 let path = path. display ( ) ;
@@ -175,9 +185,7 @@ fn event_handler(symbolizer: &symbolize::Symbolizer, data: &[u8]) -> ::std::os::
175185 return 1 ;
176186 }
177187
178- let comm = std:: str:: from_utf8 ( & event. comm )
179- . or :: < Error > ( Ok ( "<unknown>" ) )
180- . unwrap ( ) ;
188+ let comm = std:: str:: from_utf8 ( & event. comm ) . unwrap_or ( "<unknown>" ) ;
181189 println ! ( "COMM: {} (pid={}) @ CPU {}" , comm, event. pid, event. cpu_id) ;
182190
183191 if event. kstack_size > 0 {
@@ -216,7 +224,7 @@ struct Args {
216224 verbosity : u8 ,
217225}
218226
219- fn main ( ) -> Result < ( ) , Error > {
227+ fn main ( ) -> Result < ( ) , libbpf_rs :: Error > {
220228 let args = Args :: parse ( ) ;
221229 let level = match args. verbosity {
222230 0 => LevelFilter :: WARN ,
@@ -240,21 +248,22 @@ fn main() -> Result<(), Error> {
240248 let open_skel = skel_builder. open ( ) . unwrap ( ) ;
241249 let mut skel = open_skel. load ( ) . unwrap ( ) ;
242250
243- let pefds = init_perf_monitor ( freq) ;
251+ let pefds = init_perf_monitor ( freq) ? ;
244252 let _links = attach_perf_event ( & pefds, skel. progs_mut ( ) . profile ( ) ) ;
245253
246254 let maps = skel. maps ( ) ;
247255 let mut builder = libbpf_rs:: RingBufferBuilder :: new ( ) ;
248256 builder
249- . add ( maps. events ( ) , move |data| {
250- event_handler ( & symbolizer, data)
251- } )
257+ . add ( maps. events ( ) , move |data| event_handler ( & symbolizer, data) )
252258 . unwrap ( ) ;
253259 let ringbuf = builder. build ( ) . unwrap ( ) ;
254260 while ringbuf. poll ( Duration :: MAX ) . is_ok ( ) { }
255261
256262 for pefd in pefds {
257- close ( pefd) ?;
263+ close ( pefd)
264+ . map_err ( io:: Error :: from)
265+ . map_err ( libbpf_rs:: Error :: from)
266+ . context ( "failed to close perf event" ) ?;
258267 }
259268
260269 Ok ( ( ) )
0 commit comments