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,9 +25,13 @@ 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 {
// Safety: were in a signal handler that is about to call `libc::_exit`.
// Potential data races from using `*_unsynchronized` functions are perhaps
// less bad than potential deadlocks?
unsafe {
let mut print_fn_frame = 0; let mut print_fn_frame = 0;
let mut frame_count = 0; let mut frame_count = 0;
backtrace::trace(|frame| { backtrace::trace_unsynchronized(|frame| {
let found = frame.symbol_address() as usize == self.print_fn_address; let found = frame.symbol_address() as usize == self.print_fn_address;
if found { if found {
print_fn_frame = frame_count; print_fn_frame = frame_count;
@ -42,7 +46,7 @@ impl fmt::Debug for Print {
f.add_context()?; f.add_context()?;
let mut result = Ok(()); let mut result = Ok(());
let mut frame_count = 0; let mut frame_count = 0;
backtrace::trace(|frame| { backtrace::trace_unsynchronized(|frame| {
let skip = frame_count < print_fn_frame; let skip = frame_count < print_fn_frame;
frame_count += 1; frame_count += 1;
if skip { if skip {
@ -51,7 +55,7 @@ impl fmt::Debug for Print {
let mut frame_fmt = f.frame(); let mut frame_fmt = f.frame();
let mut any_symbol = false; let mut any_symbol = false;
backtrace::resolve_frame(frame, |symbol| { backtrace::resolve_frame_unsynchronized(frame, |symbol| {
any_symbol = true; any_symbol = true;
if let Err(e) = frame_fmt.symbol(frame, symbol) { if let Err(e) = frame_fmt.symbol(frame, symbol) {
result = Err(e) result = Err(e)
@ -67,6 +71,7 @@ impl fmt::Debug for Print {
result?; result?;
f.finish() f.finish()
} }
}
} }
fn print_path(fmt: &mut fmt::Formatter, path: BytesOrWideString) -> fmt::Result { fn print_path(fmt: &mut fmt::Formatter, path: BytesOrWideString) -> fmt::Result {