-
Notifications
You must be signed in to change notification settings - Fork 93
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
Segmentation fault when application stops (Ruby 3.2.2, tcmalloc or jemalloc) #292
Comments
Hey @ukolovda 👋 Can you provide us with some more information? Most importantly: Can you reproduce it? And if so, can you provide a minimal example? |
Here’s a small FROM ruby:3.2.2-slim-bookworm
RUN \
apt-get update --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
build-essential libjemalloc2 && \
ln -s /usr/lib/*-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so.2
ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2
RUN gem install mini_racer
CMD ruby -r mini_racer -e 'p MiniRacer::Context.new.eval("1+2")' I did some testing with other base images and it seems like |
ah, jemalloc 😞 We had several Ruby and mini_racer issues with jemalloc in the past, e.g. #242. I think that might be something @lloeki or @SamSaffron can take a look? |
I use jemalloc too... @jasoncodes , thank you! |
I'm wondering whether it would get confused at times as to which malloc/free symbol is which depending on how the ruby jemalloc linking happens (I think glibc is always dynamic, dunno about musl). https://github.com/jemalloc/jemalloc/wiki/Getting-Started |
Oh wait, I didn't see that:
So you're injecting jemalloc, not linking Ruby against jemalloc at Ruby build time? Do you get the same result with a Ruby build against jemalloc? |
Good question. Looks to work fine if the Ruby is built using jemalloc instead of injecting. I tested this using the first Ruby 3.2.2 w/ jemalloc base image I found which I could confirm has a working jemalloc with FROM jiting/ruby:3.2.2-slim-bookworm
RUN apt-get update && apt-get -y install build-essential
RUN gem install mini_racer
CMD ruby -r mini_racer -e 'p MiniRacer::Context.new.eval("1+2")' |
Okay so I think what might happen is:
When ruby is built statically against jemalloc, the The remaining question is why libv8 would not like having its allocator swapped with jemalloc via |
This morning I came across docker-library/ruby#182 (comment) which suggests using FROM ruby:3.2.2-slim-bookworm
RUN \
apt-get update --yes && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
build-essential libjemalloc2 patchelf && \
patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby
RUN gem install mini_racer
CMD ruby -r mini_racer -e 'p MiniRacer::Context.new.eval("1+2")' This seems like a nicer way to patch an existing Ruby as it avoids affecting all processes. Unfortunately it doesn’t solve the problem here as dynamic linking still results in libv8 using jemalloc and crashing on exit. I’m guessing within the single Ruby process, Only option right now to use mini_racer with jemalloc seems to be building Ruby with jemalloc. |
At least it seems to be more reliable. I'm running with Since this is popping up again and again over time, I'm wondering if we should add something to the troubleshooting section of the README to recommend not using jmalloc for now, or use Ruby statically build against it. What do you think, @lloeki? |
FYI Rails has merged a PR to In lieu of something in the README, may I suggest renaming this Issue to mention jemalloc? |
LD_PRELOAD can potentially cause issues with the "symbols hidden" loader for mini_racer This will unconditionally skip the loader when LD_PRELOAD is specified and points to *malloc (eg jemalloc or tcmalloc) see: #292 (comment)
LD_PRELOAD can potentially cause issues with the "symbols hidden" loader for mini_racer This will unconditionally skip the loader when LD_PRELOAD is specified and points to *malloc (eg jemalloc or tcmalloc) see: #292 (comment) (also remove minitest/pride since is it no longer loading in CI)
Note I have confirmation from @tgxworld that it resolved the issue for us, I went ahead and merged and pushed a release. will follow up with a simply run of CI with jemalloc so this does not regress. |
I don't really understand the loaders or dynamic linking enough to comment on the meat of this issue, but this suggestion seems sensible to me to help anyone trying to figure out what's crashing in the future ^ |
that is easy enough @nightpool ... edited the title. The fix feels fine, not too many memory allocators that people use in production don't have the word malloc in them. |
Do you have a stable case to reproduce, @SamSaffron? I tried several times for a while, but either issues were Ruby related and have been fixed upstream, or I could not reliably reproduce it. |
I am not sure how easy it is to get a repro, a lot of these style of issues tend to require a rather hefty application behind it. For example #300 is very hard to repro, only reliable repro I have is to spin up an entire Discourse application and run stuff on it. When I fish out all the eval mini racer makes, we no longer get a segfault. I suspect this one is similar, we would probably need a reasonably heavy Ruby process with lots of allocations to and then to spin it down. At a minimum though we can validate that |
Segfault occured when I stop the docker container.
I'm not sure that is Mini_racer trouble, but call stack is in it.
Dump is in the attachment.
MiniRacer SegFault dump.txt
The text was updated successfully, but these errors were encountered: