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

Regression in global_allocator when using prefer-dynamic on 1.71.0 and above #114518

Open
alexkornitzer opened this issue Aug 5, 2023 · 13 comments
Labels
-Cprefer-dynamic Codegen option: Prefer dynamic linking to static linking. A-allocators Area: Custom and system allocators A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@alexkornitzer
Copy link

Since 1.71.0 a regression has been added into the compiler causing segmentation faults in applications compiled using prefer-dynamic, this issue is not present in 1.70.0. It appears that the system allocator is still being used in some cases causing segmentation faults.

Code

https://github.com/alexkornitzer/dylib-errors/tree/error/jemalloc

use jemallocator::Jemalloc;

#[global_allocator]
static GLOBAL: Jemalloc = Jemalloc;

fn main() {
    let a = std::thread::spawn(move || {});
    a.join().unwrap();
    println!("didn''t crash");
}

Version it worked on

It most recently worked on: 1.70.0

Version with regression

1.71.0

Have run git bisect and the regression was introduced with the following commit: a2b1646

@alexkornitzer alexkornitzer added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Aug 5, 2023
@rustbot rustbot added needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Aug 5, 2023
@saethlin saethlin added A-linkage Area: linking into static, shared libraries and binaries A-allocators Area: Custom and system allocators T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-untriaged Untriaged performance or correctness regression. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 5, 2023
@lqd
Copy link
Member

lqd commented Aug 5, 2023

cc @bjorn3 for that bisection to #86844

@bjorn3
Copy link
Member

bjorn3 commented Aug 5, 2023

As far as I understand this shouldn't work on Windows ever before my PR as on Windows symbol preemption across dll's doesn't happen, so inside std.dll it would resolve __rust_alloc to the system allocator unconditionally. cc #100781 (comment)

@alexkornitzer
Copy link
Author

alexkornitzer commented Aug 5, 2023

This is happening for me on macOS and Linux. What is odd if that cc above is accurate is that global_allocator and -C prefer-dynamic has worked for years for me, its only with 1.71.0 and above that its now broken.

@bjorn3
Copy link
Member

bjorn3 commented Aug 6, 2023

I mean it should always have been broken on Windows as far as I understand and now is broken on other platforms too.

@alexkornitzer
Copy link
Author

Ah right gotcha, just did not get why Windows was being brought in scope but then again I was not clear that linux was my deployment target and macos my development target. Is there anything I can do to help you fix the regression?

@bjorn3
Copy link
Member

bjorn3 commented Aug 6, 2023

When I wrote #86844 I expected rustc to error on #[global_allocator] when a dylib with the allocator shim (like libstd.so) is linked. Instead it turns out that rustc accepts it just fine, but ignores #[global_allocator] entirely. For example the following doesn't panic when compiled with -Cprefer-dynamic with rustc 1.70:

use std::alloc::*;

struct MyAlloc;

unsafe impl GlobalAlloc for MyAlloc {
    unsafe fn alloc(&self, _: Layout) -> *mut u8 { todo!() }
    unsafe fn dealloc(&self, _: *mut u8, _: Layout) { todo!() }
}

#[global_allocator]
static ALLOC: MyAlloc = MyAlloc;

fn main() {
    Box::new(0);
}

and __rust_alloc comes from libstd.so. On ELF based systems it would be possible for rustc to generate the allocator shim and then thus have #[global_allocator] apply, but for Windows and likely macOS it would result in the exact kind of crash you are observing here as preempting symbols from dynamic libraries is not possible and thus the main executable and dynamic libraries will observe a different allocator. The least confusing fix is likely to give an error instead.

@alexkornitzer
Copy link
Author

So basically on 1.70.0 and below, when -C prefer-dynamic was set with a #[global_allocator] it was actually just ignoring it and using the default system allocator? If this is the case then yep raising an error makes total sense cause having silent segmentation faults is definitely not good and difficult to debug as the root cause.

@bjorn3
Copy link
Member

bjorn3 commented Aug 6, 2023

So basically on 1.70.0 and below, when -C prefer-dynamic was set with a #[global_allocator] it was actually just ignoring it and using the default system allocator?

Yes

@apiraino
Copy link
Contributor

apiraino commented Aug 8, 2023

Removing the prioritization label as the comments seem to point out that now this is the intended behaviour. Though probably can be surprising to some users, so I wonder about the actionable here.

@rustbot label -I-prioritize

@rustbot rustbot removed the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Aug 8, 2023
@alexkornitzer
Copy link
Author

@apiraino surely its important to get the compiler to throw an error here or people are going to get unexpected segfaults. This is probably not that apparent due to the rare use of both features, but rustc is now creating invalid binaries.

@apiraino
Copy link
Contributor

apiraino commented Aug 8, 2023

ok @alexkornitzer so what would be the desired behaviour in 1.71.0 instead of crashing? Some kind of safeguard preventing it (and maybe giving useful info to the user)? Thanks for helping me figuring the context :-)

@alexkornitzer
Copy link
Author

Yeah that would be ideal, which I think is what @bjorn3 suggested but never actioned? (#100781 (comment))

@apiraino
Copy link
Contributor

apiraino commented Aug 8, 2023

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-medium

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-Cprefer-dynamic Codegen option: Prefer dynamic linking to static linking. A-allocators Area: Custom and system allocators A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

7 participants