Skip to content

Capturing a backtrace prevents any future panic from printing a backtrace on Windows #165

Closed
@aloucks

Description

@aloucks

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://github.com/rust-lang/rust/blob/9ebf47851a357faa4cd97f4b1dc7835f6376e639/src/libstd/sys/windows/backtrace/mod.rs#L74

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions