From e440e265f651b4145fb3dd472da2a180c406fe39 Mon Sep 17 00:00:00 2001 From: Francisco Javier Honduvilla Coto Date: Mon, 6 Jan 2025 10:09:24 +0000 Subject: [PATCH] Do not crash while being debugged Make lighswitch debuggable by `ptrace(2)` based tools by retrying `EINTR` during poll rather than panicking. GDB and strace can now be used without crashes. --- src/profiler.rs | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/profiler.rs b/src/profiler.rs index a0e098f..0344586 100644 --- a/src/profiler.rs +++ b/src/profiler.rs @@ -20,6 +20,7 @@ use itertools::Itertools; use libbpf_rs::num_possible_cpus; use libbpf_rs::skel::SkelBuilder; use libbpf_rs::skel::{OpenSkel, Skel}; +use libbpf_rs::ErrorKind; use libbpf_rs::MapCore; use libbpf_rs::MapHandle; use libbpf_rs::MapType; @@ -408,7 +409,7 @@ impl Profiler { self.tracers.attach().expect("attach tracers"); - // New process events. + // Unwinder events. let chan_send = self.new_proc_chan_send.clone(); let perf_buffer = PerfBufferBuilder::new(&self.native_unwinder.maps.events) .pages(self.perf_buffer_bytes / page_size::get()) @@ -417,15 +418,21 @@ impl Profiler { }) .lost_cb(Self::handle_lost_events) .build() - // TODO: Instead of unwrap, consume and emit any error, with - // .expect() perhaps? - .unwrap(); - - let _poll_thread = thread::spawn(move || loop { - perf_buffer.poll(Duration::from_millis(100)).expect("poll"); + .expect("set up perf buffer for unwinder events"); + + let _unwinder_poll_thread = thread::spawn(move || loop { + match perf_buffer.poll(Duration::from_millis(100)) { + Ok(_) => {} + Err(err) => { + if err.kind() != ErrorKind::Interrupted { + error!("polling events perf buffer failed with {:?}", err); + break; + } + } + } }); - // Trace events are received here, such as memory unmaps. + // Tracer events. let tracers_send = self.tracers_chan_send.clone(); let tracers_events_perf_buffer = PerfBufferBuilder::new(&self.tracers.maps.tracer_events) .pages(self.perf_buffer_bytes / page_size::get()) @@ -440,14 +447,18 @@ impl Profiler { warn!("lost {} events from the tracers", lost_count); }) .build() - // TODO: Instead of unwrap, consume and emit any error, with - // .expect() perhaps? - .unwrap(); + .expect("set up perf buffer for tracer events"); let _tracers_poll_thread = thread::spawn(move || loop { - tracers_events_perf_buffer - .poll(Duration::from_millis(100)) - .expect("poll"); + match tracers_events_perf_buffer.poll(Duration::from_millis(100)) { + Ok(_) => {} + Err(err) => { + if err.kind() != ErrorKind::Interrupted { + error!("polling tracers perf buffer failed with {:?}", err); + break; + } + } + } }); let profile_receive = self.profile_receive.clone();