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

fix weak memory bug in TLS on Windows #124281

Merged
merged 1 commit into from
Apr 24, 2024
Merged

fix weak memory bug in TLS on Windows #124281

merged 1 commit into from
Apr 24, 2024

Conversation

RalfJung
Copy link
Member

We need to store the key after we register the dtor.

Now I hope there isn't also some other reason why we have to actually register the dtor last... @joboet is there a reason you picked this particular order in #102655?

Fixes #123583

@rustbot
Copy link
Collaborator

rustbot commented Apr 23, 2024

r? @ChrisDenton

rustbot has assigned @ChrisDenton.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added O-windows Operating system: Windows S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 23, 2024
@joboet
Copy link
Member

joboet commented Apr 23, 2024

Ah yes, this is clearly a bug.

Now I hope there isn't also some other reason why we have to actually register the dtor last... @joboet is there a reason you picked this particular order in #102655?

There was: the destructor may be called as soon as it is registered so I wanted to make sure that the key was set at that point, as TlsGetValue needs to read from a correct key.

You can fix this by skipping the TLS variable in run_dtors if the stored key is zero.

@RalfJung
Copy link
Member Author

Ah, makes sense. And in the Miri testcase, we don't have a thread-exit racing with a key-init so we wouldn't hit this.

I have updated the code.

@RalfJung
Copy link
Member Author

I extended the Miri test to also cover this, that triggered the bug immediately:

//! Regression test for <https://github.com/rust-lang/rust/issues/123583>.
use std::thread;

fn with_thread_local1() {
    thread_local! { static X: Box<u8> = Box::new(0); }
    X.with(|_x| {})
}


fn with_thread_local2() {
    thread_local! { static Y: Box<u8> = Box::new(0); }
    Y.with(|_y| {})
}

fn main() {
    // Here we have two threads racing on initializing the thread-local
    // and (on Windows without target_thread_local) adding it to the global dtor list.
    let t = thread::spawn(with_thread_local1);
    with_thread_local1();
    t.join().unwrap();

    // Here we have one thread running the destructors racing with another thread initializing a thread-local.
    // The second thread adds a destructor that could be picked up by the first thread.
    let t = thread::spawn(|| { /* immediately just run destructors */});
    with_thread_local2(); // initialize thread-local
    t.join().unwrap();
}

@joboet
Copy link
Member

joboet commented Apr 24, 2024

Thank you very much, especially for the detailed comments!
@bors r+

@bors
Copy link
Contributor

bors commented Apr 24, 2024

📌 Commit d5d714b has been approved by joboet

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 24, 2024
@joboet joboet assigned joboet and unassigned ChrisDenton Apr 24, 2024
@RalfJung
Copy link
Member Author

The regression tests are being added on the Miri side in rust-lang/miri#3501.

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 24, 2024
Rollup of 6 pull requests

Successful merges:

 - rust-lang#123316 (Test `#[unix_sigpipe = "inherit"]` with both `SIG_DFL` and `SIG_IGN`)
 - rust-lang#123794 (More DefineOpaqueTypes::Yes)
 - rust-lang#123881 (Bump Fuchsia versions)
 - rust-lang#124281 (fix weak memory bug in TLS on Windows)
 - rust-lang#124282 (windows fill_utf16_buf: explain the expected return value)
 - rust-lang#124308 (Add diagnostic item for `std::iter::Enumerate`)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 24, 2024
Rollup of 6 pull requests

Successful merges:

 - rust-lang#123316 (Test `#[unix_sigpipe = "inherit"]` with both `SIG_DFL` and `SIG_IGN`)
 - rust-lang#123794 (More DefineOpaqueTypes::Yes)
 - rust-lang#123881 (Bump Fuchsia versions)
 - rust-lang#124281 (fix weak memory bug in TLS on Windows)
 - rust-lang#124282 (windows fill_utf16_buf: explain the expected return value)
 - rust-lang#124308 (Add diagnostic item for `std::iter::Enumerate`)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 4eda876 into rust-lang:master Apr 24, 2024
12 checks passed
@rustbot rustbot added this to the 1.79.0 milestone Apr 24, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 24, 2024
Rollup merge of rust-lang#124281 - RalfJung:win-tls, r=joboet

fix weak memory bug in TLS on Windows

We need to store the `key` *after* we register the dtor.

Now I hope there isn't also some other reason why we have to actually register the dtor last... `@joboet` is there a reason you picked this particular order in rust-lang#102655?

Fixes rust-lang#123583
@RalfJung RalfJung deleted the win-tls branch April 25, 2024 10:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-windows Operating system: Windows S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Miri sometimes reports memory leak in thread-local storage on *-pc-windows-gnu
5 participants