TLS dtor panics abort the process
Today a destructor in TLS which panics will abort the process:
struct Foo;
impl Drop for Foo {
fn drop(&mut self) { panic!() }
}
thread_local!(static FOO: Foo = Foo);
pub fn main() {
FOO.with(|_| {});
}
When compiled and run (note that it must be run on a recent system due to #19776):
thread '<main>' panicked at 'explicit panic', foo.rs:4
fatal runtime error: Could not unwind stack, error = 5
zsh: illegal hardware instruction ./foo
The reason behind this is that the context in which TLS destructors are running is different than the execution of the main thread itself (e.g. there is no try/catch block).
Is this (a) desirable and (b) should we change it?
Triage: no change in behavior here.
Steve Klabnik at 2015-12-18 22:26:04
It would be nice if this was a clean and intentional abort, which would probably be achieved whenever we make
extern "C"functions abort to avoid UB (but we can do it sooner manually).The
fatal runtime error: Could not unwind stack, error = 5message could lean one to believe this is some sort of bug elsewhere (i.e. in the implementation of panics).For example, in https://github.com/rust-lang/rust/issues/63804#issuecomment-523973998 I noticed that the message doesn't have anything to do with the way proc macros and libstd('s panic runtime) interact, which is what I initially assumed.
Eduard-Mihai Burtescu at 2019-08-23 11:00:58
An especially bad side effect is that, when this happens in a test, the test doesn’t always fail.
struct Foo; impl Drop for Foo { fn drop(&mut self) { panic!() } } thread_local!(static FOO: Foo = Foo); #[test] pub fn test() { FOO.with(|_| {}); }$ cargo test Finished test [unoptimized + debuginfo] target(s) in 0.00s Running target/debug/deps/panicking_test-85130fa46b54f758 running 1 test thread 'test test ... test' panicked at 'explicit panic', src/main.rs:5:9 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s fatal runtime error: failed to initiate panic, error 5 $ echo $? 0The exit status of
cargo testis either 0 or 101 nondeterministically, and seems to be more likely to be 0 in a large project, which means that the bug that caused this panic can easily remain uncaught.Edit: This turns out to be an independent problem, due to libtest failing to actually wait for its test threads to exit; I opened a PR as #81367.
Anders Kaseorg at 2021-01-24 22:45:51