-
Notifications
You must be signed in to change notification settings - Fork 94
Make unprefixed consistently override the system allocator #109
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
Conversation
|
Welcome @madsmtm! It looks like this is your first PR to tikv/jemallocator 🎉 |
cf52544 to
1deee1e
Compare
| use super::*; | ||
|
|
||
| #[used] | ||
| static USED_MALLOC: unsafe extern "C" fn(usize) -> *mut c_void = malloc; |
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 references on how these statics are processed?
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.
There's the reference on #[used], and the equivalent Clang attribute and GCC attribute.
But these are somewhat vague, perhaps intentionally so as this is very much a linker concept? I don't really have a good reference on linkers, the best I can do is reference this piece of source code in rustc that talks about a workaround for static libs, and the following section from the manual page for ld64:
A static library (aka static archive) is a collection of .o files with a table of contents that lists the global symbols in the .o files. ld will only pull .o files out of a static library if needed to resolve some symbol reference. Unlike traditional linkers, ld will continually search a static library while linking.
(Note that Rust .rlibs are internally archives / static libraries, and so the rules for static libaries apply to them as well).
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.
Or if you have more specific questions about how things work then I can try to answer them, to the best of my ability?
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.
I see. How about adding a test to show it work as expected? You can add a dylib crate that allocs in the root directory and then add a test crate that links both the dylib and jemalloc-sys. If it works as expected the test shoud be able to use jemalloc's free to dealloc the pointer from dylib.
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.
Sorry for the delay.
I found the closest thing to a reference link, and have rewritten the docs around it to hopefully be clearer.
I have also added two tests:
malloc_and_libc_are_interoperable_when_overridden, which tests that the overriding actually works on macOS.test-dylib, which tests that when linking a dylib, the symbol is correctly overridden. Note that I couldn't reproduce it with the current nightly, so something might have changed recently that makes this hack redundant nowadays? Unsure, though it doesn't hurt to have in any case.
Failed CI run of the first commit with just the tests: https://github.com/madsmtm/jemallocator/actions/runs/15490515399
Successful CI run after the second commit: https://github.com/madsmtm/jemallocator/actions/runs/15490429305
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.
I got the test-dylib test to not work without this PR, have pushed that as the first commit instead.
Failed CI run: https://github.com/madsmtm/jemallocator/actions/runs/17785024568
Succesful CI run: https://github.com/madsmtm/jemallocator/actions/runs/17784954361
070e78b to
c6670be
Compare
|
Ping @BusyJay, could you take a look? This would be nice to get in, it'd simplify |
| target_vendor = "apple" | ||
| ))] | ||
| #[used] | ||
| static USED_ZONE_REGISTER: unsafe extern "C" fn() = { |
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.
Better make it a new feature so that we can land it without a new minor version.
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.
I'd argue this is more in the category "bugfix" rather than "feature"; the unprefixed_malloc_on_supported_platforms just plain didn't work on macOS before (unless you inserted these statics yourself like rustc), and now it does.
Or do you fear this will have a chance of breaking something for users?
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.
unprefixed_malloc_on_supported_platforms just plain didn't work on macOS before
It actually works if unprefixed_malloc_on_supported_platforms is interpreted as its name instead of overriding system allocator. The symbol is still unprefixed on MacOS in the past and future.
Or do you fear this will have a chance of breaking something for users?
Yes, it's known not to override system allocator on MacOS.
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.
Right. In the last commit, I've changed it to:
unprefixed_malloc_on_supported_platforms = []
override = ["unprefixed_malloc_on_supported_platforms"]
I've also made the statics only get emitted with that feature enabled.
- A test that checks that jemalloc's malloc and libc's free are interoperable when unprefixed. - A test that checks that using unprefixed with a shared library still overrides the symbols in the shared library. Signed-off-by: Mads Marquart <[email protected]>
Signed-off-by: Mads Marquart <[email protected]>
ea4c927 to
bd94cbe
Compare
|
I tested this a bit more thoroughly together with |
a7ea610 to
b2813fc
Compare
|
Rest LGTM |
25dd274 to
82b4a4e
Compare
|
I think I've fixed the things you requested now |
Signed-off-by: Mads Marquart <[email protected]>
82b4a4e to
fc4d596
Compare
|
Fixed CI |
|
Thank you! |
|
Would it be possible to get this published as v0.6.1? I can make a PR for it if you want? |
…zelmann Simplify `jemalloc` setup In the past, `#[used]` had to appear in the top-level crate to have a consistent effect on the linker. This has been fixed a while ago for ELF with the introduction of the `symbols.o` file in rust-lang#95604, and more recently for Mach-O in rust-lang#133832, which means that libraries can now implement the required workarounds themselves. This allows moving these `#[used]` declarations out of our `main.rs`. Specifically, I have moved them into `tikv-jemalloc-sys` where they belong in tikv/jemallocator#109 and done the same for `mimalloc` in purpleprotocol/mimalloc_rust#146 (in case we want to experiment with switching to that one day). Test with: ```sh ./x build library src/tools/rustdoc src/tools/clippy --set rust.jemalloc=true # macOS lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b _rjem_je_zone_register (lldb) run # Should breakpoint, this means that the allocator was properly linked # Linux lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b malloc (lldb) run # Should breakpoint, inspect that the `malloc` symbol comes from the `rustc` binary and not from `libc` ``` try-job: `aarch64-gnu` try-job: `dist-aarch64-linux` try-job: `dist-x86_64-musl` try-job: `dist-x86_64-apple` try-job: `dist-aarch64-apple`
…zelmann Simplify `jemalloc` setup In the past, `#[used]` had to appear in the top-level crate to have a consistent effect on the linker. This has been fixed a while ago for ELF with the introduction of the `symbols.o` file in rust-lang#95604, and more recently for Mach-O in rust-lang#133832, which means that libraries can now implement the required workarounds themselves. This allows moving these `#[used]` declarations out of our `main.rs`. Specifically, I have moved them into `tikv-jemalloc-sys` where they belong in tikv/jemallocator#109 and done the same for `mimalloc` in purpleprotocol/mimalloc_rust#146 (in case we want to experiment with switching to that one day). Test with: ```sh ./x build library src/tools/rustdoc src/tools/clippy --set rust.jemalloc=true # macOS lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b _rjem_je_zone_register (lldb) run # Should breakpoint, this means that the allocator was properly linked # Linux lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b malloc (lldb) run # Should breakpoint, inspect that the `malloc` symbol comes from the `rustc` binary and not from `libc` ``` try-job: `aarch64-gnu` try-job: `dist-aarch64-linux` try-job: `dist-x86_64-musl` try-job: `dist-x86_64-apple` try-job: `dist-aarch64-apple`
…zelmann Simplify `jemalloc` setup In the past, `#[used]` had to appear in the top-level crate to have a consistent effect on the linker. This has been fixed a while ago for ELF with the introduction of the `symbols.o` file in rust-lang#95604, and more recently for Mach-O in rust-lang#133832, which means that libraries can now implement the required workarounds themselves. This allows moving these `#[used]` declarations out of our `main.rs`. Specifically, I have moved them into `tikv-jemalloc-sys` where they belong in tikv/jemallocator#109 and done the same for `mimalloc` in purpleprotocol/mimalloc_rust#146 (in case we want to experiment with switching to that one day). Test with: ```sh ./x build library src/tools/rustdoc src/tools/clippy --set rust.jemalloc=true # macOS lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b _rjem_je_zone_register (lldb) run # Should breakpoint, this means that the allocator was properly linked # Linux lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b malloc (lldb) run # Should breakpoint, inspect that the `malloc` symbol comes from the `rustc` binary and not from `libc` ``` try-job: `aarch64-gnu` try-job: `dist-aarch64-linux` try-job: `dist-x86_64-musl` try-job: `dist-x86_64-apple` try-job: `dist-aarch64-apple`
…zelmann Simplify `jemalloc` setup In the past, `#[used]` had to appear in the top-level crate to have a consistent effect on the linker. This has been fixed a while ago for ELF with the introduction of the `symbols.o` file in rust-lang#95604, and more recently for Mach-O in rust-lang#133832, which means that libraries can now implement the required workarounds themselves. This allows moving these `#[used]` declarations out of our `main.rs`. Specifically, I have moved them into `tikv-jemalloc-sys` where they belong in tikv/jemallocator#109 and done the same for `mimalloc` in purpleprotocol/mimalloc_rust#146 (in case we want to experiment with switching to that one day). Test with: ```sh ./x build library src/tools/rustdoc src/tools/clippy --set rust.jemalloc=true # macOS lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b _rjem_je_zone_register (lldb) run # Should breakpoint, this means that the allocator was properly linked # Linux lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b malloc (lldb) run # Should breakpoint, inspect that the `malloc` symbol comes from the `rustc` binary and not from `libc` ``` try-job: `aarch64-gnu` try-job: `dist-aarch64-linux` try-job: `dist-x86_64-musl` try-job: `dist-x86_64-apple` try-job: `dist-aarch64-apple`
Rollup merge of #146627 - madsmtm:jemalloc-simplify, r=jdonszelmann Simplify `jemalloc` setup In the past, `#[used]` had to appear in the top-level crate to have a consistent effect on the linker. This has been fixed a while ago for ELF with the introduction of the `symbols.o` file in #95604, and more recently for Mach-O in #133832, which means that libraries can now implement the required workarounds themselves. This allows moving these `#[used]` declarations out of our `main.rs`. Specifically, I have moved them into `tikv-jemalloc-sys` where they belong in tikv/jemallocator#109 and done the same for `mimalloc` in purpleprotocol/mimalloc_rust#146 (in case we want to experiment with switching to that one day). Test with: ```sh ./x build library src/tools/rustdoc src/tools/clippy --set rust.jemalloc=true # macOS lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b _rjem_je_zone_register (lldb) run # Should breakpoint, this means that the allocator was properly linked # Linux lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b malloc (lldb) run # Should breakpoint, inspect that the `malloc` symbol comes from the `rustc` binary and not from `libc` ``` try-job: `aarch64-gnu` try-job: `dist-aarch64-linux` try-job: `dist-x86_64-musl` try-job: `dist-x86_64-apple` try-job: `dist-aarch64-apple`
Simplify `jemalloc` setup In the past, `#[used]` had to appear in the top-level crate to have a consistent effect on the linker. This has been fixed a while ago for ELF with the introduction of the `symbols.o` file in rust-lang/rust#95604, and more recently for Mach-O in rust-lang/rust#133832, which means that libraries can now implement the required workarounds themselves. This allows moving these `#[used]` declarations out of our `main.rs`. Specifically, I have moved them into `tikv-jemalloc-sys` where they belong in tikv/jemallocator#109 and done the same for `mimalloc` in purpleprotocol/mimalloc_rust#146 (in case we want to experiment with switching to that one day). Test with: ```sh ./x build library src/tools/rustdoc src/tools/clippy --set rust.jemalloc=true # macOS lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b _rjem_je_zone_register (lldb) run # Should breakpoint, this means that the allocator was properly linked # Linux lldb -- ./build/host/stage1/bin/rustc -vV (lldb) b malloc (lldb) run # Should breakpoint, inspect that the `malloc` symbol comes from the `rustc` binary and not from `libc` ``` try-job: `aarch64-gnu` try-job: `dist-aarch64-linux` try-job: `dist-x86_64-musl` try-job: `dist-x86_64-apple` try-job: `dist-aarch64-apple`
The goal is to move the various workarounds for this feature in
rustcto thejemalloc-syscrate instead.I'm not entirely sure of the history here, but it is possible this was not done in the past because
#[used]used to not work in libraries, see rust-lang/rust#95604 and rust-lang/rust#133491? In any case, we should be able to do it now.