Skip to content

Commit

Permalink
Enable the default panic unwind hook to print backtraces again
Browse files Browse the repository at this point in the history
The default panic unwind hook attempts to print the backtrace by
first initializing DbgHelp with `SymInitializeW`. The documentation
states that this can't be called again until after `SymCleanup` is
called first. If called prior to cleanup, it returns a non-success
result. The default unwind hook detects this error and never tries
to print the backtrace.

This PR installs a new panic handler that first calls `SymCleanup`
prior to calling the previously installed (or default) panic hook.

Fixes rust-lang#165
  • Loading branch information
aloucks committed Apr 24, 2019
1 parent d8ea02e commit 02c0b33
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,29 @@ unsafe fn dbghelp_init() {

static mut INITIALIZED: bool = false;

#[cfg(feature = "std")]
fn dbghelp_init_cleanup() {
let default_hook = std::panic::take_hook();
std::panic::set_hook(std::boxed::Box::new(move |panic_info| {
// The default unwind hook calls `SymInitializeW`, which will fail and prevent
// the panic backtrace from being printed if we do not first call `SymCleanup`.
unsafe {
INITIALIZED = false;
dbghelp::SymCleanup(processthreadsapi::GetCurrentProcess());
}
default_hook(panic_info);
}))
}

#[cfg(not(feature = "std"))]
fn dbghelp_init_cleanup() {}

if !INITIALIZED {
INITIALIZED = true;

dbghelp::SymInitializeW(processthreadsapi::GetCurrentProcess(),
0 as *mut _,
minwindef::TRUE);
INITIALIZED = true;
dbghelp_init_cleanup();
}
}
}

0 comments on commit 02c0b33

Please sign in to comment.