Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # 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
# for free to join this conversation on GitHub. Already have an account? # 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