There are 2 issues with capturing stack traces on Windows.
Specifically with the resolving of the symbols of the stack traces.
Note that this affects both the stack traces captured by Rust and Tracy.
Both Rust and Tracy use the dbghelp.dll symbol helper to resolve symbols.
The first issue is that dbghelp.dll is single threaded and all its functions need to be externally synchronized.
Rust uses a named Windows mutex to synchronize access to dbghelp.dll between the standard library and the backtrace-rs crate when both are used.
The first commit in this PR makes Tracy use the same named Mutex.
Not properly synchronizing can lead to partially corrupted stacktraces.
Example corrupted stacktrace
Note the `` at the top probably caused by some race condition
```
stack backtrace:
0: 0x7ff7a900767d -
1: 0x7ff7a9014bc9 -
2: 0x7ff7a9006011 -
3: 0x7ff7a90093c7 -
4: 0x7ff7a9008fb9 -
5: 0x7ff7a9009a72 -
6: 0x7ff7a900990f -
7: 0x7ff7a9007d6f -
8: 0x7ff7a9009526 -
9: 0x7ff7a903dbc4 -
10: 0x7ff7a90012ee - tracy_client_stacktrace::main
at C:\Dev\tracy-client-stacktrace-issue\src\main.rs:5
11: 0x7ff7a900138b - core::ops::function::FnOnce::call_once >
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c\library\core\src\ops\function.rs:250
12: 0x7ff7a900142e - core::hint::black_box
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c\library\core\src\hint.rs:389
13: 0x7ff7a900142e - std::sys::backtrace::__rust_begin_short_backtrace >
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c\library\std\src\sys\backtrace.rs:152
14: 0x7ff7a9001401 - std::rt::lang_start::closure$0 >
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c\library\std\src\rt.rs:162
15: 0x7ff7a9004279 - std::rt::lang_start_internal::closure$2
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\std\src\rt.rs:141
16: 0x7ff7a9004279 - std::panicking::try::do_call
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\std\src\panicking.rs:557
17: 0x7ff7a9004279 - std::panicking::try
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\std\src\panicking.rs:521
18: 0x7ff7a9004279 - std::panic::catch_unwind
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\std\src\panic.rs:350
19: 0x7ff7a9004279 - std::rt::lang_start_internal
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library\std\src\rt.rs:141
20: 0x7ff7a90013da - std::rt::lang_start >
at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c\library\std\src\rt.rs:161
21: 0x7ff7a9001309 - main
22: 0x7ff7a903b918 - invoke_main
at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
23: 0x7ff7a903b918 - __scrt_common_main_seh
at D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
24: 0x7ffaad70257d - BaseThreadInitThunk
25: 0x7ffaae1eaf28 - RtlUserThreadStart
```
The second issue is that Rust and Tracy initialize the symbol helper in different ways.
Since Rust 1.78.0 the compiler no longer includes absolute paths to .pdb files in the binary (https://github.com/rust-lang/rust/pull/121297). That can make the symbol resolution fail because by default only the current working directory is searched for .pdb files.
There was also a corresponding PR to backtrace-rs to include the executable location in the search path (https://github.com/rust-lang/backtrace-rs/pull/584), but when Tracy initializes dbghelp.dll first, the modules get loaded before the search path gets modified.
The second commit in this PR fixes that by capturing and resolving a backtrace using the standard library before Tracy does the initialization.
This fixes #101.
There are 2 issues with capturing stack traces on Windows. Specifically with the resolving of the symbols of the stack traces. Note that this affects both the stack traces captured by Rust and Tracy.
Both Rust and Tracy use the
dbghelp.dll
symbol helper to resolve symbols. The first issue is thatdbghelp.dll
is single threaded and all its functions need to be externally synchronized. Rust uses a named Windows mutex to synchronize access todbghelp.dll
between the standard library and thebacktrace-rs
crate when both are used. The first commit in this PR makes Tracy use the same named Mutex. Not properly synchronizing can lead to partially corrupted stacktraces.Example corrupted stacktrace
Note the `The second issue is that Rust and Tracy initialize the symbol helper in different ways. Since Rust 1.78.0 the compiler no longer includes absolute paths to .pdb files in the binary (https://github.com/rust-lang/rust/pull/121297). That can make the symbol resolution fail because by default only the current working directory is searched for .pdb files. There was also a corresponding PR to
backtrace-rs
to include the executable location in the search path (https://github.com/rust-lang/backtrace-rs/pull/584), but when Tracy initializesdbghelp.dll
first, the modules get loaded before the search path gets modified. The second commit in this PR fixes that by capturing and resolving a backtrace using the standard library before Tracy does the initialization. This fixes #101.