-
-
Notifications
You must be signed in to change notification settings - Fork 463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Linking with mold breaks initialization of thread local storage in Rust under FreeBSD on AMD64 #1338
Comments
Good news, it seems not to reproduce with mold 1.11.0 so it's probably possible to bisect this if you don't have a more direct way of arriving at the cause. |
This bisected to c395da1, which was a fix for #1216
|
I don't have a FreeBSD machine, and it is not easy to set up a new one. I usually use Docker, but that works only for Linux guests. Did you know if there's a FreeBSD machine that I can login to debug this issue? |
Hey, thanks for your interest in looking into this. You should be able to
|
Thank you for the test environment. The above fix should work for you. You can remove the test environment now. |
Thanks for the fix; that was fast! ❤️ |
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 rui314/mold#1338 for reference.
Compiling fish-shell from git master with rust 1.79.0 (latest from FreeBSD pkg repos) and mold 2.31.0 (latest from pkg repos) causes random segfaults that were traced back to misbehaving
thread_local!
static variables.Everything starts off fine, but after a few seconds of using the shell (typing at the prompt) it segfaults due to an incorrect tls thread id making some assertions fail. I edited the code some to add some debug stderr output to see what was going on and it seems that either after a certain number of times (but more likely from certain call sites) thread local storage is not being initialized upon first access by a new thread, and it is retaining its default (zero) value.
For reference, here's the (patched) function in question that assigns a custom thread id based off of an atomic variable that is incremented once per thread:
Under FreeBSD, compiling with environment variable
RUSTFLAGS
set to-C link-args=--ld-path=/usr/local/bin/mold
, the following incorrect behavior is observed:eprintln!()
call printing the mapping from the rust-native thread id to the simpleusize
fish thread id when they first accessthread_id()
and then they print the secondeprintln!()
call upon that and each subsequent invocationThreadId(1)
) is observed callingthread_id()
but not entering thethread_local!()
initializer; it prints the secondeprintln!()
call with an incorrectid
value of0
and is never observed to enter thethread_local!()
initializer.Compiling and running fish from master under FreeBSD:
This behavior is observed with the default (DEBUG) build, without any optimizations or architecture-specific optimizations enabled. Tested under FreeBSD 13.3. The same procedure without the
RUSTFLAGS
environment variable set to specify building withmold
results in a binary that works correctly.Happy to post any differential outputs of the mold-linked and normal builds as needed to help pin this down. For what it's worth, I do not observe any similar behavior using mold to link fish under Linux/AMD64.
Edit: this version of the function more directly illustrates the problem; the
debug_assert_ne!()
call results in a panic because TLS was not initialized. Again, this doesn't happen right off the bat; it's after some time has passed/from a particular call site.The text was updated successfully, but these errors were encountered: