-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Never inline Windows dtor access #100007
Never inline Windows dtor access #100007
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
Note that if I instead use
|
88d6658
to
847f461
Compare
#[thread_local] | ||
static mut DESTRUCTORS: Vec<(*mut u8, unsafe extern "C" fn(*mut u8))> = Vec::new(); | ||
|
||
// Ensure this can never be inlined because otherwise this may break in dylibs. | ||
// See #44391. | ||
#[inline(never)] | ||
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { | ||
DESTRUCTORS.push((t, dtor)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @michaelwoerister @bjorn3 Could we make it so that on Windows you cannot use #[thread_local]
from a function that may end up unable to actually reference that thread-local? See also linked issue:
(Though I have no idea what's happening here, since it doesn't change when/where these functions are codegenned, they're not generic and didn't have #[inline(always)]
on it).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Though I have no idea what's happening here, since it doesn't change when/where these functions are codegenned, they're not generic and didn't have #[inline(always)] on it).
Not sure either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, the context for this PR is #94820 where I was seeing local test failures related to dtors (but this didn't seem to affect CI). However, I'm not able to reproduce it now and unfortunately back then I was rather lax in my documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance LTO or ThinLTO was enabled in a way that could result in some of these definitions crossing between LLVM modules?
Alternatively, if you move the functions into different modules than the #[thread_local] static
, could you sometimes end up with them being in separate CGUs and somehow that being enough to cause an issue?
Sadly that's also still not enough because of the whole "per-DLL/EXE" aspect.
It might be something like ThinLTO'd librustc_driver-*.so
against libstd-*.so
but the libstd-*.so
s I'm seeing in nightly don't seem to have any LLVM bitcode sections so it can't be that.
(A custom build of libstd-*.so
might still have LLVM bitcode - also just noticed I'm looking at Linux .so
s not Windows .dll
s, but I doubt that would affect whether we put LLVM bitcode in them?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, in general, ThinLTO can cause small functions like this one to be inlined into other modules. I haven't looked at this specific case though.
I'm basically happy to just r+ this, but it seems like it might be worth doing a little bit more digging here around potential causes. Maybe not, though, since the change is trivial. |
OK, let's get it merged. @bors r+ I won't have time to investigate further. Do we have enough info for opening an issue? |
Does this not essentially have the same root cause as the linked issue (#44391)? Windows TLS access should not be jumping exe/dll boundaries under any circumstances. See also our TLS macro which cannot be marked inline on Windows due to the behavior of dylibs. |
Sure, but the question is why it jumped a dll boundary in the first place. |
Right but neither should any TLS access is what I'm saying. Solving the underlying problem would also solve this and all related issues. I'm not at all against opening an issue for this specific instance of the problem, it's just that |
…ichaelwoerister Never inline Windows dtor access Inlining can cause problem If used in a Rust dylib. See rust-lang#44391. r? `@Mark-Simulacrum`
☀️ Test successful - checks-actions |
Finished benchmarking commit (3694b7d): comparison url. Instruction count
Max RSS (memory usage)Results
CyclesThis benchmark run did not return any relevant results for this metric. If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf. @rustbot label: -perf-regression Footnotes |
Rollup of 7 pull requests Successful merges: - rust-lang#92744 (Check if enum from foreign crate has any non exhaustive variants when attempting a cast) - rust-lang#99337 (rustdoc: simplify highlight.rs) - rust-lang#100007 (Never inline Windows dtor access) - rust-lang#100030 (cleanup code w/ pointers in std a little) - rust-lang#100192 ( Remove duplicated temporaries creating during box derefs elaboration) - rust-lang#100247 (Generalize trait object generic param check to aliases.) - rust-lang#100374 (Improve crate selection on rustdoc search results page) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This change increased minimal size of msvc empty cdylib dll from 10KB to 120KB, bringing in panicking, fmt and demangle with no user code at all. Because now Vec<>.push() call actually always exists, I suppose |
Inlining can cause problem If used in a Rust dylib. See #44391.
r? @Mark-Simulacrum