Skip to content

Commit 286cdc8

Browse files
committed
[backtraces]: look for the begin symbol only after seeing end
On `x86_64-pc-windows-msvc`, we often get backtraces which look like this: ``` 10: 0x7ff77e0e9be5 - std::panicking::rust_panic_with_hook 11: 0x7ff77e0e11b4 - std::sys_common::backtrace::__rust_begin_short_backtrace::h5769736bdb11136c 12: 0x7ff77e0e116f - std::sys_common::backtrace::__rust_end_short_backtrace::h61c7ecb1b55338ae 13: 0x7ff77e0f89dd - std::panicking::begin_panic::h8e60ef9f82a41805 14: 0x7ff77e0e108c - d 15: 0x7ff77e0e1069 - c 16: 0x7ff77e0e1059 - b 17: 0x7ff77e0e1049 - a 18: 0x7ff77e0e1039 - core::ptr::drop_in_place<std::rt::lang_start<()>::{{closure}}>::h1bfcd14d5e15ba81 19: 0x7ff77e0e1186 - std::sys_common::backtrace::__rust_begin_short_backtrace::h5769736bdb11136c 20: 0x7ff77e0e100c - std::rt::lang_start::{{closure}}::ha054184bbf9921e3 ``` Notice that `__rust_begin_short_backtrace` appears on frame 11 before `__rust_end_short_backtrace` on frame 12. This is because in typical release binaries without debug symbols, dbghelp.dll, which we use to walk and symbolize the stack, does not know where CGU internal functions start or end and so the closure invoked by `__rust_end_short_backtrace` is incorrectly described as `__rust_begin_short_backtrace` because it happens to be near that symbol. While that can obviously change, this has been happening quite consistently since #75048. Since this is a very small change to the std and the change makes sense by itself, I think this is worth doing. This doesn't completely resolve the situation for release binaries on Windows, since without debug symbols, the stack printed can still show incorrect symbol names (this is why the test uses `#[no_mangle]`) but it does slightly improve the situation in that you see the same backtrace you would see with `RUST_BACKTRACE=full` or in a debugger (without the uninteresting bits at the top and bottom).
1 parent 3fda708 commit 286cdc8

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

library/std/src/sys_common/backtrace.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::
7575
hit = true;
7676
if print_fmt == PrintFmt::Short {
7777
if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
78-
if sym.contains("__rust_begin_short_backtrace") {
78+
if start && sym.contains("__rust_begin_short_backtrace") {
7979
stop = true;
8080
return;
8181
}

src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs

+5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@
1010
// check-run-results
1111
// exec-env:RUST_BACKTRACE=1
1212

13+
// We need to normalize out frame 5 because without debug info, dbghelp.dll doesn't know where CGU
14+
// internal functions like `main` start or end and so it will return whatever symbol happens
15+
// to be located near the address.
16+
// normalize-stderr-test: "5: .*" -> "5: some Rust fn"
17+
1318
// Backtraces are pretty broken in general on i686-pc-windows-msvc (#62897).
1419
// only-x86_64-pc-windows-msvc
1520

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
thread 'main' panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:43:5
1+
thread 'main' panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:48:5
22
stack backtrace:
3+
0: std::panicking::begin_panic
4+
1: d
5+
2: c
6+
3: b
7+
4: a
8+
5: some Rust fn
39
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

0 commit comments

Comments
 (0)