Skip to content
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

Main thread thread-local destructors are not always run #126858

Closed
4 tasks
RalfJung opened this issue Jun 23, 2024 · 2 comments
Closed
4 tasks

Main thread thread-local destructors are not always run #126858

RalfJung opened this issue Jun 23, 2024 · 2 comments
Labels
A-destructors Area: Destructors (`Drop`, …) A-thread-locals Area: Thread local storage (TLS) C-bug Category: This is a bug. O-android Operating system: Android O-linux Operating system: Linux O-musl Target: The musl libc

Comments

@RalfJung
Copy link
Member

RalfJung commented Jun 23, 2024

Simplified testcase:

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println!("Foo dtor");
    }
}

thread_local!(static FOO: Foo = Foo);

fn main() {
    FOO.with(|_| {});
}

This should print Foo dtor, but prints nothing on some targets:

  • musl (e.g. i686-unknown-linux-musl, x86_64-unknown-linux-musl)
  • android (e.g. arm-linux-androideabi)
  • Linux with glibc before 2.18
  • Maybe more?

Here's a more complicated testcase that also involves initializing a destructor while destructors are being run; ideally this will be added to the test suite at some point:

struct Bar;

impl Drop for Bar {
    fn drop(&mut self) {
        println!("Bar dtor");
    }
}

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println!("Foo dtor");
        // We initialize another thread-local inside the dtor, which is an interesting corner case.
        thread_local!(static BAR: Bar = Bar);
        BAR.with(|_| {});
    }
}

thread_local!(static FOO: Foo = Foo);

fn main() {
    FOO.with(|_| {});
}
@RalfJung RalfJung added the O-musl Target: The musl libc label Jun 23, 2024
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Jun 23, 2024
@traviscross traviscross added C-bug Category: This is a bug. A-destructors Area: Destructors (`Drop`, …) A-thread-locals Area: Thread local storage (TLS) and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Jun 23, 2024
@RalfJung RalfJung changed the title Main thread thread-local destructors are not run on musl targets Main thread thread-local destructors are not run on musl, android Jun 24, 2024
@RalfJung RalfJung added the O-android Operating system: Android label Jun 24, 2024
@bjorn3
Copy link
Member

bjorn3 commented Jun 24, 2024

For musl the thread-local destructors registered with pthread_key_create seem to get run by __pthread_tsd_run_dtors, which is only called from pthread_exit. For bionic (Android's libc) they get run from pthread_key_clean_all, which too is only called from pthread_exit. It doesn't seem to be documented anywhere officially if exiting the main thread without pthread_exit should invoke thread-local destructors. Several stack overflow posts say it doesn't which is the behavior observed for musl and bionic, while glibc has been calling them since 2004 (bminor/glibc@3fa21fd).

@RalfJung RalfJung changed the title Main thread thread-local destructors are not run on musl, android Main thread thread-local destructors are not always run Jul 6, 2024
@RalfJung RalfJung added the O-linux Operating system: Linux label Jul 6, 2024
@RalfJung
Copy link
Member Author

RalfJung commented Jul 6, 2024

Closing in favor of the original, #28129.

@RalfJung RalfJung closed this as completed Jul 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-destructors Area: Destructors (`Drop`, …) A-thread-locals Area: Thread local storage (TLS) C-bug Category: This is a bug. O-android Operating system: Android O-linux Operating system: Linux O-musl Target: The musl libc
Projects
None yet
Development

No branches or pull requests

4 participants