Description
As the title states, backtraces are not printed if the program panics after a backtrace was captured with the library.
$ rustc --version -v
rustc 1.34.0 (91856ed52 2019-04-10)
binary: rustc
commit-hash: 91856ed52c58aa5ba66a015354d1cc69e9779bdf
commit-date: 2019-04-10
host: x86_64-pc-windows-msvc
release: 1.34.0
LLVM version: 8.0
With RUST_BACKTRACE=1
let bt = Backtrace::new();
println!("{:?}", bt); // <-- this backtrace is printed
panic!("Oops!"); // <-- the backtrace here is not printed
I tracked it down to this commit: 3cfb76a
The cleanup code was removed.
Changing the example to the following allows for both backtraces to print:
let bt = Backtrace::new();
println!("{:?}", bt);
unsafe {
let handle = winapi::um::processthreadsapi::GetCurrentProcess();
winapi::um::dbghelp::SymCleanup(handle);
}
panic!("Oops!");
The runtime panic-unwind code is checking the result of SymInitialize
which is probably an error due to double initialization.
https://docs.microsoft.com/en-us/windows/desktop/api/dbghelp/nf-dbghelp-syminitializew
A process that calls SymInitialize should not call it again unless it calls SymCleanup first.
Perhaps the old behavior could be restored with deferred symbol loading:
https://docs.microsoft.com/en-us/windows/desktop/api/Dbghelp/nf-dbghelp-symsetoptions
SYMOPT_DEFERRED_LOADS0x00000004 | Symbols are not loaded until a reference is made requiring the symbols be loaded. This is the fastest, most efficient way to use the symbol handler.
Alternatively, the runtime panic-unwind code could perhaps always call SymCleanup
first (and ignore the error) prior to calling SymInitialize
. As far as I can tell, calling SymCleanup
without first initializing returns an error code but is otherwise harmless.