Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid allocation in the signal handler to fix a deadlock #24890

Merged
merged 3 commits into from Nov 27, 2019
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Prev

Avoid locking in the signal handler

  • Loading branch information
SimonSapin committed Nov 27, 2019
commit 5bcd2f564297aacc04189fd6001c0ab0b03ffad2
@@ -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()
}
}
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.