aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2019-11-27 21:10:18 +0100
committerSimon Sapin <simon.sapin@exyr.org>2019-11-27 21:56:39 +0100
commit5bcd2f564297aacc04189fd6001c0ab0b03ffad2 (patch)
tree2e2f74ef79e8b8a17c84c4cba2990fa9fc158a02
parent99804eb5a6a6c2f4b1384f735cc43f2cc8b61b4f (diff)
downloadservo-5bcd2f564297aacc04189fd6001c0ab0b03ffad2.tar.gz
servo-5bcd2f564297aacc04189fd6001c0ab0b03ffad2.zip
Avoid locking in the signal handler
-rw-r--r--ports/glutin/backtrace.rs79
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()
+ }
}
}