1
- use std:: io:: Error ;
1
+ use std:: io;
2
2
use std:: mem;
3
3
use std:: time:: Duration ;
4
4
@@ -9,6 +9,7 @@ use clap::Parser;
9
9
10
10
use libbpf_rs:: skel:: OpenSkel as _;
11
11
use libbpf_rs:: skel:: SkelBuilder as _;
12
+ use libbpf_rs:: ErrorExt as _;
12
13
13
14
use nix:: unistd:: close;
14
15
@@ -40,7 +41,7 @@ struct stacktrace_event {
40
41
ustack : [ u64 ; MAX_STACK_DEPTH ] ,
41
42
}
42
43
43
- fn init_perf_monitor ( freq : u64 ) -> Vec < i32 > {
44
+ fn init_perf_monitor ( freq : u64 ) -> Result < Vec < i32 > , libbpf_rs :: Error > {
44
45
let nprocs = libbpf_rs:: num_possible_cpus ( ) . unwrap ( ) ;
45
46
let pid = -1 ;
46
47
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> {
56
57
attr. flags = 1 << 10 ; // freq = 1
57
58
( 0 ..nprocs)
58
59
. 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
+ }
61
67
} )
62
68
. collect ( )
63
69
}
@@ -72,7 +78,11 @@ fn attach_perf_event(
72
78
. collect ( )
73
79
}
74
80
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
+ ) {
76
86
let code_info = code_info. as_ref ( ) . map ( |code_info| {
77
87
let path = code_info. to_path ( ) ;
78
88
let path = path. display ( ) ;
@@ -175,9 +185,7 @@ fn event_handler(symbolizer: &symbolize::Symbolizer, data: &[u8]) -> ::std::os::
175
185
return 1 ;
176
186
}
177
187
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>" ) ;
181
189
println ! ( "COMM: {} (pid={}) @ CPU {}" , comm, event. pid, event. cpu_id) ;
182
190
183
191
if event. kstack_size > 0 {
@@ -216,7 +224,7 @@ struct Args {
216
224
verbosity : u8 ,
217
225
}
218
226
219
- fn main ( ) -> Result < ( ) , Error > {
227
+ fn main ( ) -> Result < ( ) , libbpf_rs :: Error > {
220
228
let args = Args :: parse ( ) ;
221
229
let level = match args. verbosity {
222
230
0 => LevelFilter :: WARN ,
@@ -240,21 +248,22 @@ fn main() -> Result<(), Error> {
240
248
let open_skel = skel_builder. open ( ) . unwrap ( ) ;
241
249
let mut skel = open_skel. load ( ) . unwrap ( ) ;
242
250
243
- let pefds = init_perf_monitor ( freq) ;
251
+ let pefds = init_perf_monitor ( freq) ? ;
244
252
let _links = attach_perf_event ( & pefds, skel. progs_mut ( ) . profile ( ) ) ;
245
253
246
254
let maps = skel. maps ( ) ;
247
255
let mut builder = libbpf_rs:: RingBufferBuilder :: new ( ) ;
248
256
builder
249
- . add ( maps. events ( ) , move |data| {
250
- event_handler ( & symbolizer, data)
251
- } )
257
+ . add ( maps. events ( ) , move |data| event_handler ( & symbolizer, data) )
252
258
. unwrap ( ) ;
253
259
let ringbuf = builder. build ( ) . unwrap ( ) ;
254
260
while ringbuf. poll ( Duration :: MAX ) . is_ok ( ) { }
255
261
256
262
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" ) ?;
258
267
}
259
268
260
269
Ok ( ( ) )
0 commit comments