From c6bbacc703ebed81b2d0dc8855189d56c61a7d86 Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Sat, 31 Aug 2024 12:38:10 -0500 Subject: [PATCH] Catch tls issues caused by linker bug Worth including because mold is rather popular in the rust world and because the bug affects mold versions coincident with the development of the fish rust port. The bug affects all currently released versions of mold from 2.30.0 (Mar 2024) onwards under at least FreeBSD (though quite likely other platforms as well). See https://github.com/rui314/mold/issues/1338 for reference. --- src/threads.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/threads.rs b/src/threads.rs index 06b59649f..fb1eb9ec3 100644 --- a/src/threads.rs +++ b/src/threads.rs @@ -87,7 +87,7 @@ fn main_thread_id() -> usize { /// via `Arc`, and uses as Mutex on 32-bit platforms (or those without a 64-bit atomic CAS). #[inline(always)] fn thread_id() -> usize { - static THREAD_COUNTER: AtomicUsize = AtomicUsize::new(0); + static THREAD_COUNTER: AtomicUsize = AtomicUsize::new(1); // It would be much nicer and faster to use #[thread_local] here, but that's nightly only. // This is still faster than going through Thread::thread_id(); it's something like 15ns // for each `Thread::thread_id()` call vs 1-2 ns with `#[thread_local]` and 2-4ns with @@ -95,7 +95,11 @@ fn thread_id() -> usize { thread_local! { static THREAD_ID: usize = THREAD_COUNTER.fetch_add(1, Ordering::Relaxed); } - THREAD_ID.with(|id| *id) + let id = THREAD_ID.with(|id| *id); + // This assertion is only here to reduce hair loss in case someone runs into a known linker bug; + // as it's not here to catch logic errors in our own code, it can be elided in release mode. + debug_assert_ne!(id, 0, "TLS storage not initialized!"); + id } #[test]