diff --git a/library/std/src/sys_common/backtrace.rs b/library/std/src/sys_common/backtrace.rs index a549770d8b378..e6a099f0e81a0 100644 --- a/library/std/src/sys_common/backtrace.rs +++ b/library/std/src/sys_common/backtrace.rs @@ -75,7 +75,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: hit = true; if print_fmt == PrintFmt::Short { if let Some(sym) = symbol.name().and_then(|s| s.as_str()) { - if sym.contains("__rust_begin_short_backtrace") { + if start && sym.contains("__rust_begin_short_backtrace") { stop = true; return; } diff --git a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs new file mode 100644 index 0000000000000..fd01337296fb7 --- /dev/null +++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.rs @@ -0,0 +1,49 @@ +// Regression test for #87481: short backtrace formatting cut off the entire stack trace. + +// Codegen-units is specified here so that we can replicate a typical rustc invocation which +// is not normally limited to 1 CGU. This is important so that the `__rust_begin_short_backtrace` +// and `__rust_end_short_backtrace` symbols are not marked internal to the CGU and thus will be +// named in the symbol table. +// compile-flags: -O -Ccodegen-units=8 + +// run-fail +// check-run-results +// exec-env:RUST_BACKTRACE=1 + +// We need to normalize out frame 5 because without debug info, dbghelp.dll doesn't know where CGU +// internal functions like `main` start or end and so it will return whatever symbol happens +// to be located near the address. +// normalize-stderr-test: "5: .*" -> "5: some Rust fn" + +// Backtraces are pretty broken in general on i686-pc-windows-msvc (#62897). +// only-x86_64-pc-windows-msvc + +fn main() { + a(); +} + +// Make these no_mangle so dbghelp.dll can figure out the symbol names. + +#[no_mangle] +#[inline(never)] +fn a() { + b(); +} + +#[no_mangle] +#[inline(never)] +fn b() { + c(); +} + +#[no_mangle] +#[inline(never)] +fn c() { + d(); +} + +#[no_mangle] +#[inline(never)] +fn d() { + panic!("d was called"); +} diff --git a/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr new file mode 100644 index 0000000000000..799a8b30e997b --- /dev/null +++ b/src/test/ui/panics/panic-short-backtrace-windows-x86_64.run.stderr @@ -0,0 +1,9 @@ +thread 'main' panicked at 'd was called', $DIR/panic-short-backtrace-windows-x86_64.rs:48:5 +stack backtrace: + 0: std::panicking::begin_panic + 1: d + 2: c + 3: b + 4: a + 5: some Rust fn +note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.