diff options
author | Simon Sapin <simon.sapin@exyr.org> | 2019-11-27 21:10:18 +0100 |
---|---|---|
committer | Simon Sapin <simon.sapin@exyr.org> | 2019-11-27 21:56:39 +0100 |
commit | 5bcd2f564297aacc04189fd6001c0ab0b03ffad2 (patch) | |
tree | 2e2f74ef79e8b8a17c84c4cba2990fa9fc158a02 | |
parent | 99804eb5a6a6c2f4b1384f735cc43f2cc8b61b4f (diff) | |
download | servo-5bcd2f564297aacc04189fd6001c0ab0b03ffad2.tar.gz servo-5bcd2f564297aacc04189fd6001c0ab0b03ffad2.zip |
Avoid locking in the signal handler
-rw-r--r-- | ports/glutin/backtrace.rs | 79 |
1 files changed, 42 insertions, 37 deletions
diff --git a/ports/glutin/backtrace.rs b/ports/glutin/backtrace.rs index 0c089336557..6e5a8390042 100644 --- a/ports/glutin/backtrace.rs +++ b/ports/glutin/backtrace.rs @@ -25,47 +25,52 @@ struct Print { impl fmt::Debug for Print { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - let mut print_fn_frame = 0; - let mut frame_count = 0; - backtrace::trace(|frame| { - let found = frame.symbol_address() as usize == self.print_fn_address; - if found { - print_fn_frame = frame_count; - } - frame_count += 1; - !found - }); + // Safety: we’re 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 frame_count = 0; + backtrace::trace_unsynchronized(|frame| { + let found = frame.symbol_address() as usize == self.print_fn_address; + if found { + print_fn_frame = frame_count; + } + frame_count += 1; + !found + }); - 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 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_unsynchronized(|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) + let mut frame_fmt = f.frame(); + let mut any_symbol = false; + backtrace::resolve_frame_unsynchronized(frame, |symbol| { + 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() }); - 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() + result?; + f.finish() + } } } |