Closed
Description
Hello, rust-team!
Code
I tried this code:
#[test]
fn spawn_in_atexit_main() {
unsafe { libc::atexit(spawn_in_atexit) };
}
extern "C" fn spawn_in_atexit() {
let _ = std::thread::spawn(|| {
println!("Thread spawned in atexit");
});
}
I expected to see this happen: thread spawned normally
Instead, this happened: panic at std::thread::spawnhook::run_spawn_hooks
because it tries to talk to TLS which is not available inside of atexit context. Earlier versions of thread
didn't have this hooks functionality and were OK spawning inside atexit
and we tested it on Win, Mac and Linux.
Functionality to spawn thread inside atexit
is very important as it is a silver bullet workaround to execute some TLS-using code from atexit
context.
Version it worked on
It most recently worked on: at least 1.75
Version with regression
rustc --version --verbose
:
rustc 1.85.1 (4eb161250 2025-03-15)
binary: rustc
commit-hash: 4eb161250e340c8f48f66e2b929ef4a5bed7c181
commit-date: 2025-03-15
host: x86_64-unknown-linux-gnu
release: 1.85.1
LLVM version: 19.1.7
Backtrace
Backtrace
thread 'main' panicked at library/std/src/thread/local.rs:272:26:
cannot access a Thread Local Storage value during or after destruction: AccessError
stack backtrace:
0: rust_begin_unwind
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/panicking.rs:692:5
1: core::panicking::panic_fmt
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/panicking.rs:75:14
2: core::result::unwrap_failed
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/result.rs:1704:5
3: core::result::Result<T,E>::expect
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/result.rs:1061:23
4: std::thread::local::LocalKey<T>::with
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/thread/local.rs:272:9
5: std::thread::spawnhook::run_spawn_hooks
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/thread/spawnhook.rs:116:29
6: std::thread::Builder::spawn_unchecked_
at /home/hatter/.rustup/toolchains/1.85.0-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:512:13
7: std::thread::Builder::spawn_unchecked
at /home/hatter/.rustup/toolchains/1.85.0-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:469:32
8: std::thread::Builder::spawn
at /home/hatter/.rustup/toolchains/1.85.0-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:401:18
9: std::thread::spawn
at /home/hatter/.rustup/toolchains/1.85.0-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/thread/mod.rs:734:20
10: atexit::spawn_in_atexit
at ./tests/atexit.rs:88:13
11: __run_exit_handlers
at ./stdlib/exit.c:108:8
12: __GI_exit
at ./stdlib/exit.c:138:3
13: __libc_start_call_main
at ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
14: __libc_start_main_impl
at ./csu/../csu/libc-start.c:360:3
15: _start
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread 'main' panicked at library/core/src/panicking.rs:218:5:
panic in a function that cannot unwind
stack backtrace:
0: 0x65482003492a - std::backtrace_rs::backtrace::libunwind::trace::h88deb10bd0145eb8
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
1: 0x65482003492a - std::backtrace_rs::backtrace::trace_unsynchronized::he1036f5481c14dff
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x65482003492a - std::sys::backtrace::_print_fmt::hecc345b6e70c4b20
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/sys/backtrace.rs:66:9
3: 0x65482003492a - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::he089f96442833f67
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/sys/backtrace.rs:39:26
4: 0x654820060683 - core::fmt::rt::Argument::fmt::h1f77cded99c71a14
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/fmt/rt.rs:177:76
5: 0x654820060683 - core::fmt::write::h2f210ed4c94745cb
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/fmt/mod.rs:1440:21
6: 0x654820030423 - std::io::Write::write_fmt::h7de08171ab770fb2
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/io/mod.rs:1887:15
7: 0x654820034772 - std::sys::backtrace::BacktraceLock::print::h810fbd31421329e6
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/sys/backtrace.rs:42:9
8: 0x654820035e60 - std::panicking::default_hook::{{closure}}::hbaad47ed9dc6356d
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/panicking.rs:295:22
9: 0x654820035c40 - std::panicking::default_hook::h24e207139139d40a
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/panicking.rs:322:9
10: 0x6548200365c2 - std::panicking::rust_panic_with_hook::ha9131beeb2ddc506
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/panicking.rs:828:13
11: 0x654820036336 - std::panicking::begin_panic_handler::{{closure}}::h1bba0eaeb6da506f
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/panicking.rs:694:13
12: 0x654820034e29 - std::sys::backtrace::__rust_end_short_backtrace::h1d1ca3eade483f4c
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/sys/backtrace.rs:168:18
13: 0x654820035ffd - rust_begin_unwind
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/std/src/panicking.rs:692:5
14: 0x65481ebd45ed - core::panicking::panic_nounwind_fmt::runtime::hdd2d1a56a8b6cee7
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/panicking.rs:117:22
15: 0x65481ebd45ed - core::panicking::panic_nounwind_fmt::h0d5ff668f956fac4
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/intrinsics/mod.rs:3869:9
16: 0x65481ebd4682 - core::panicking::panic_nounwind::h385b7d9bda51382d
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/panicking.rs:218:5
17: 0x65481ebd4846 - core::panicking::panic_cannot_unwind::h757b6ea37bf9b60a
at /rustc/4d91de4e48198da2e33413efdcd9cd2cc0c46688/library/core/src/panicking.rs:307:5
18: 0x65481ec436e9 - atexit::spawn_in_atexit::h8fbdd131c26eac2f
at /home/hatter/work/repos/zenoh/zenoh/tests/atexit.rs:87:1
19: 0x7982d2a47a76 - __run_exit_handlers
at ./stdlib/exit.c:108:8
20: 0x7982d2a47bbe - __GI_exit
at ./stdlib/exit.c:138:3
21: 0x7982d2a2a1d1 - __libc_start_call_main
at ./csu/../sysdeps/nptl/libc_start_call_main.h:74:3
22: 0x7982d2a2a28b - __libc_start_main_impl
at ./csu/../csu/libc-start.c:360:3
23: 0x65481ebd4f15 - _start
24: 0x0 - <unknown>
thread caused non-unwinding panic. aborting.
error: test failed, to rerun pass `-p zenoh --test atexit`
Caused by:
process didn't exit successfully: `/home/hatter/work/repos/zenoh/target/debug/deps/atexit-f97afb099485217a spawn_in_atexit_main --exact --show-output` (signal: 6, SIGABRT: process abort signal)
* The terminal process "cargo 'test', '--package', 'zenoh', '--test', 'atexit', '--', 'spawn_in_atexit_main', '--exact', '--show-output'" terminated with exit code: 101.
* Terminal will be reused by tasks, press any key to close it.