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

jemalloc is not getting used coherently on all platforms. #9925

Closed
alexcrichton opened this issue Oct 18, 2013 · 5 comments · Fixed by #9933
Closed

jemalloc is not getting used coherently on all platforms. #9925

alexcrichton opened this issue Oct 18, 2013 · 5 comments · Fixed by #9933

Comments

@alexcrichton
Copy link
Member

UPDATED REPORT

I decided to investigate what was happening and why anything was working at all today, and I found some surprising results. My investigation involved breaking on uv_fs_open and then seeing what happened. One of the first things that this function does is invoke strdup, which is then later deallocated with free. I followed these calls to figure out which malloc (part of strdup) and free were getting used. This data was all collected by running ./$platform/stage0/bin/rustc and just seeing what happened.

platform malloc free global_heap::malloc_raw global_heap::exchange_free
x86_64-unknown-linux jemalloc jemalloc jemalloc jemalloc
i686-unknown-linux libc jemalloc libc libc
x86_64-apple-darwin libc libc ? ?
i686-apple-darwin libc libc ? ?

It appears that 32-bit linux is the worst off where the allocator is being mismatched, but I'm not certain that it's not being mismatched on other platforms.

ORIGINAL REPORT

I was stepping through i386 linux recently, and got this backtrace:

Breakpoint 8, __GI___libc_malloc (bytes=16) at malloc.c:2910                                                        
2910    malloc.c: No such file or directory.                                                                        
(gdb) bt                                                                                                            
#0  __GI___libc_malloc (bytes=16) at malloc.c:2910                                                                  
#1  0xf7ac196f in rt::global_heap::malloc_raw::hbc5969e10a864a8a4::v0.9$x2dpre ()                                   
   from /home/alex/rust/x86_64-unknown-linux-gnu/stage1/lib/rustc/i686-unknown-linux-gnu/lib/libstd-6c65cf4b443341b1
-0.9-pre.so                                                                                                         
#2  0xf7b6124e in rt::uv::uvio::EventLoop$UvEventLoop::remote_callback::h14d1de56cbaf539eaVaQ::v0.9$x2dpre ()       
   from /home/alex/rust/x86_64-unknown-linux-gnu/stage1/lib/rustc/i686-unknown-linux-gnu/lib/libstd-6c65cf4b443341b1
-0.9-pre.so                                                                                                         
#3  0xf7b00d66 in rt::sched::Scheduler::make_handle::hfe732d5489154f1873aL::v0.9$x2dpre ()                          
   from /home/alex/rust/x86_64-unknown-linux-gnu/stage1/lib/rustc/i686-unknown-linux-gnu/lib/libstd-6c65cf4b443341b1
-0.9-pre.so                                                                                                         
#4  0xf7b5bae1 in rt::sched::Scheduler::run_sched_once::hf3525925b944a5173a8::v0.9$x2dpre ()                        
   from /home/alex/rust/x86_64-unknown-linux-gnu/stage1/lib/rustc/i686-unknown-linux-gnu/lib/libstd-6c65cf4b443341b1
-0.9-pre.so                                                                                                         
#5  0xf7b71896 in rt::uv::uvio::__extensions__::start::anon::expr_fn::aq ()                                         
   from /home/alex/rust/x86_64-unknown-linux-gnu/stage1/lib/rustc/i686-unknown-linux-gnu/lib/libstd-6c65cf4b443341b1

This appears to indicate that we are not using jemalloc for the exchange or managed heaps. I did see jemalloc get used by libuv though (but jemalloc is linked statically to libuv)

@metajack
Copy link
Contributor

The recent bug with immediates that we found upgrading Servo to the latest Rust also had a stacktrace that started with jemalloc. That was doing a free of an owned pointer inside an enum variant. So it's used in at least some cases. The specific struct was this: https://github.com/mozilla/servo/blob/master/src/components/main/layout/float_context.rs#L49-L52 and the stacktrace is here: https://gist.github.com/metajack/7010750

@alexcrichton
Copy link
Member Author

This is causing some serious bugs. On OSX, it looks like free/malloc are dyld_lookup_XXX so they're always resolved to libc (we're not using jemalloc at all), and on linux it appears that we're allocating half the time with libc and half the time with jemalloc. Then we free one with the other and receive only sadness in return.

@metajack
Copy link
Contributor

@huonw asked if that stack trace was from linux. It was.

@alexcrichton
Copy link
Member Author

Updated the issue title and description with the results of some more investigation.

bors added a commit that referenced this issue Oct 18, 2013
As discovered in #9925, it turns out that we weren't using jemalloc on most
platforms. Additionally, on some platforms we were using it incorrectly and
mismatching the libc version of malloc with the jemalloc version of malloc.

Additionally, it's not clear that using jemalloc is indeed a large performance
win in particular situtations. This could be due to building jemalloc
incorrectly, or possibly due to using jemalloc incorrectly, but it is unclear at
this time.

Until jemalloc can be confirmed to integrate correctly on all platforms and has
verifiable large performance wins on platforms as well, it shouldn't be part of
the default build process. It should still be available for use via the
LD_PRELOAD trick on various architectures, but using it as the default allocator
for everything would require guaranteeing that it works in all situtations,
which it currently doesn't.

Closes #9925
@emberian
Copy link
Member

Yikes!

dmitry-stripe pushed a commit to DarkDimius/lmdb that referenced this issue Oct 11, 2018
`strdup` internally uses glibc malloc to allocate the returned char *.
This means that if application is using some other allocator,
say jemalloc, `free`-ing result of `strdup` is an undefined behavior.

References: https://stackoverflow.com/questions/32944390/what-is-the-rationale-for-not-including-strdup-in-the-c-standard
            jemalloc/jemalloc#365
            rust-lang/rust#9925
dmitry-stripe pushed a commit to DarkDimius/lmdb that referenced this issue Oct 11, 2018
`strdup` internally uses glibc malloc to allocate the returned char *.
This means that if application is using some other allocator,
say jemalloc, `free`-ing result of `strdup` is an undefined behavior.

References: https://stackoverflow.com/questions/32944390/what-is-the-rationale-for-not-including-strdup-in-the-c-standard
            jemalloc/jemalloc#365
            rust-lang/rust#9925
DarkDimius added a commit to DarkDimius/lmdb that referenced this issue Apr 3, 2020
`strdup` internally uses glibc malloc to allocate the returned char *.
This means that if application is using some other allocator,
say jemalloc, `free`-ing result of `strdup` is an undefined behavior.

References: https://stackoverflow.com/questions/32944390/what-is-the-rationale-for-not-including-strdup-in-the-c-standard
            jemalloc/jemalloc#365
            rust-lang/rust#9925
jez pushed a commit to jez/lmdb that referenced this issue Mar 22, 2023
`strdup` internally uses glibc malloc to allocate the returned char *.
This means that if application is using some other allocator,
say jemalloc, `free`-ing result of `strdup` is an undefined behavior.

References: https://stackoverflow.com/questions/32944390/what-is-the-rationale-for-not-including-strdup-in-the-c-standard
            jemalloc/jemalloc#365
            rust-lang/rust#9925
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants