Files
rust/tests/ui/panics/panic-abort-backtrace-without-debuginfo.rs
Martin Nordholts fe66eaa67a Fix backtraces with -C panic=abort on linux; emit unwind tables by default
The linux backtrace unwinder relies on unwind tables to work properly,
and generating and printing a backtrace is done by for example the
default panic hook.

Begin emitting unwind tables by default again with `-C panic=abort` (see
history below) so that backtraces work.

History
=======

Backtraces with `-C panic=abort` used to work in Rust 1.22 but broke in
Rust 1.23, because in 1.23 we stopped emitting unwind tables with `-C
panic=abort` (see 24cc38e3b0).

In 1.45 (see cda994633e) a workaround in the form
of `-C force-unwind-tables=yes` was added.

`-C panic=abort` was added in [Rust
1.10](https://blog.rust-lang.org/2016/07/07/Rust-1.10/#what-s-in-1-10-stable)
and the motivation was binary size and compile time. But given how
confusing that behavior has turned out to be, it is better to make
binary size optimization opt-in with `-C force-unwind-tables=no` rather
than default since the current default breaks backtraces.

Besides, if binary size is a primary concern, there are many other
tricks that can be used that has a higher impact.
2025-10-02 19:46:41 +02:00

58 lines
2.0 KiB
Rust

//! Test that with `-C panic=abort` the backtrace is not cut off by default
//! (i.e. without using `-C force-unwind-tables=yes`) by ensuring that our own
//! functions are in the backtrace. If we just check one function it might be
//! the last function, so make sure the backtrace can continue by checking for
//! two functions. Regression test for
//! <https://github.com/rust-lang/rust/issues/81902>.
//@ run-pass
//@ needs-subprocess
// We want to test if unwind tables are emitted by default. We must make sure
// to disable debuginfo to test that, because enabling debuginfo also means that
// unwind tables are emitted, which prevents us from testing what we want.
// We also need to set opt-level=0 to avoid optimizing away our functions.
//@ compile-flags: -C panic=abort -C opt-level=0 -C debuginfo=0
//@ no-prefer-dynamic
//@ ignore-apple
//@ ignore-arm-unknown-linux-gnueabihf FIXME(#146996) Try removing this once #146996 has been fixed.
//@ ignore-msvc Backtraces on Windows requires debuginfo which we can't use here
static FN_1: &str = "this_function_must_be_in_the_backtrace";
fn this_function_must_be_in_the_backtrace() {
and_this_function_too();
}
static FN_2: &str = "and_this_function_too";
fn and_this_function_too() {
panic!("generate panic backtrace");
}
fn run_test() {
let output = std::process::Command::new(std::env::current_exe().unwrap())
.arg("whatever")
.env("RUST_BACKTRACE", "full")
.output()
.unwrap();
let backtrace = std::str::from_utf8(&output.stderr).unwrap();
fn assert(function_name: &str, backtrace: &str) {
assert!(
backtrace.contains(function_name),
"ERROR: no `{}` in stderr! actual stderr: {}",
function_name,
backtrace
);
}
assert(FN_1, backtrace);
assert(FN_2, backtrace);
}
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() == 1 {
run_test();
} else {
this_function_must_be_in_the_backtrace();
}
}