Avoid locking in the signal handler

This commit is contained in:
Simon Sapin 2019-11-27 21:10:18 +01:00
parent 99804eb5a6
commit 5bcd2f5642

View file

@ -25,47 +25,52 @@ struct Print {
impl fmt::Debug for Print { impl fmt::Debug for Print {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let mut print_fn_frame = 0; // Safety: were in a signal handler that is about to call `libc::_exit`.
let mut frame_count = 0; // Potential data races from using `*_unsynchronized` functions are perhaps
backtrace::trace(|frame| { // less bad than potential deadlocks?
let found = frame.symbol_address() as usize == self.print_fn_address; unsafe {
if found { let mut print_fn_frame = 0;
print_fn_frame = frame_count; let mut frame_count = 0;
} backtrace::trace_unsynchronized(|frame| {
frame_count += 1; let found = frame.symbol_address() as usize == self.print_fn_address;
!found if found {
}); print_fn_frame = frame_count;
let mode = PrintFmt::Short;
let mut p = print_path;
let mut f = backtrace::BacktraceFmt::new(fmt, mode, &mut p);
f.add_context()?;
let mut result = Ok(());
let mut frame_count = 0;
backtrace::trace(|frame| {
let skip = frame_count < print_fn_frame;
frame_count += 1;
if skip {
return true
}
let mut frame_fmt = f.frame();
let mut any_symbol = false;
backtrace::resolve_frame(frame, |symbol| {
any_symbol = true;
if let Err(e) = frame_fmt.symbol(frame, symbol) {
result = Err(e)
} }
frame_count += 1;
!found
}); });
if !any_symbol {
if let Err(e) = frame_fmt.print_raw(frame.ip(), None, None, None) { let mode = PrintFmt::Short;
result = Err(e) let mut p = print_path;
let mut f = backtrace::BacktraceFmt::new(fmt, mode, &mut p);
f.add_context()?;
let mut result = Ok(());
let mut frame_count = 0;
backtrace::trace_unsynchronized(|frame| {
let skip = frame_count < print_fn_frame;
frame_count += 1;
if skip {
return true
} }
}
result.is_ok() let mut frame_fmt = f.frame();
}); let mut any_symbol = false;
result?; backtrace::resolve_frame_unsynchronized(frame, |symbol| {
f.finish() any_symbol = true;
if let Err(e) = frame_fmt.symbol(frame, symbol) {
result = Err(e)
}
});
if !any_symbol {
if let Err(e) = frame_fmt.print_raw(frame.ip(), None, None, None) {
result = Err(e)
}
}
result.is_ok()
});
result?;
f.finish()
}
} }
} }