Skip to content

fix weak memory bug in TLS on Windows - #124281

Merged
bors merged 1 commit into
rust-lang:masterfrom
RalfJung:win-tls
Apr 24, 2024
Merged

fix weak memory bug in TLS on Windows#124281
bors merged 1 commit into
rust-lang:masterfrom
RalfJung:win-tls

Conversation

@RalfJung

Copy link
Copy Markdown
Member

We need to store the keyafter 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
Copy Markdown
Collaborator

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

@rustbotrustbot 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

joboet commented Apr 23, 2024

Copy link
Copy Markdown
Member

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
Copy Markdown
MemberAuthor

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.

Comment threadlibrary/std/src/sys/pal/windows/thread_local_key.rs Outdated
@RalfJung

Copy link
Copy Markdown
MemberAuthor

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;fnwith_thread_local1(){thread_local!{staticX:Box<u8> = Box::new(0);}X.with(|_x| {})}fnwith_thread_local2(){thread_local!{staticY:Box<u8> = Box::new(0);}Y.with(|_y| {})}fnmain(){// 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
Copy Markdown
Member

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

@bors

bors commented Apr 24, 2024

Copy link
Copy Markdown
Collaborator

📌 Commit d5d714b has been approved by joboet

It is now in the queue for this repository.

@borsbors 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
@joboetjoboet assigned joboet and unassigned ChrisDentonApr 24, 2024
@RalfJung

Copy link
Copy Markdown
MemberAuthor

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

@fmeasefmease mentioned this pull request Apr 24, 2024
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:masterApr 24, 2024
@rustbotrustbot 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?
Fixesrust-lang#123583
@RalfJung
RalfJung deleted the win-tls branch April 25, 2024 10:27
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

O-windowsOperating system: WindowsS-waiting-on-borsStatus: Waiting on bors to run and complete tests. Bors will change the label on completion.T-libsRelevant 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

@RalfJung@rustbot@joboet@bors@ChrisDenton