mini_racer: 0.4.0 crashes on aarch64-linux for Ruby 2.7 + 3.0; LoadError with 2.5 and 2.6 (via Docker for Mac on M1)

I used the following to check if mini_racer works with Docker for Mac on Apple Silicon. RUBY_PLATFORM is aarch64-linux.

# frozen_string_literal: true

require "bundler/inline"

gemfile do
  source "https://rubygems.org"

  gem "mini_racer", "0.4.0"
  gem "libv8-node", "15.14.0.1"
end

puts "RUBY_VERSION : #{RUBY_VERSION}"
puts "RUBY_PLATFORM: #{RUBY_PLATFORM}"
puts "MiniRacer::LIBV8_NODE_VERSION: #{MiniRacer::LIBV8_NODE_VERSION}"
puts "Libv8::Node::VERSION: #{Libv8::Node::VERSION}"
puts "Libv8::Node::NODE_VERSION: #{Libv8::Node::NODE_VERSION}"
puts "Libv8::Node::LIBV8_VERSION: #{Libv8::Node::LIBV8_VERSION}"

ctx = MiniRacer::Context.new
ctx.eval("1+1")

I’m on Docker for Mac 3.3.3 (64133). For testing, I run the above script like this:

docker run -it --rm -v "$(pwd)":/app ruby:2.7.2 ruby /app/minimal.rb

Ruby 3

Ruby 2.7

Ruby 2.7.0, 2.7.1, 2.7.2 and 2.7.3 results in *** stack smashing detected ***: <unknown> terminated. Not sure how to supply more detail here.

Ruby 2.6 and 2.5

Ruby 2.5.8 and 2.6.7 gives a LoadError:

/usr/local/bundle/gems/libv8-node-15.12.0.0.beta1-aarch64-linux/lib/libv8/node.rb:2:in `require': cannot load such file -- libv8-node/location (LoadError)
        from /usr/local/bundle/gems/libv8-node-15.12.0.0.beta1-aarch64-linux/lib/libv8/node.rb:2:in `<top (required)>'
        from /usr/local/bundle/gems/libv8-node-15.12.0.0.beta1-aarch64-linux/lib/libv8-node.rb:1:in `require'
        from /usr/local/bundle/gems/libv8-node-15.12.0.0.beta1-aarch64-linux/lib/libv8-node.rb:1:in `<top (required)>'
        from /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:81:in `require'
        from /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:81:in `block (2 levels) in require'
        from /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:76:in `each'
        from /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:76:in `block in require'
        from /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:65:in `each'
        from /usr/local/lib/ruby/2.6.0/bundler/runtime.rb:65:in `require'
        from /usr/local/lib/ruby/2.6.0/bundler/inline.rb:70:in `gemfile'
        from /app/minimal.rb:8:in `<main>'

mini_racer currently supports Ruby >= 2.3. I tested all available versions of 2.7 and 3, but only the latest one of 2.6 and 2.5. One could consider making 2.5 the minimal supported version, as 2.3 and 2.4 are EOL for a while now. Ruby version requirement has been increased to >= 2.5.

I’m happy to provide more data if it helps. I also have a larger project with substantial use of mini_racer I’m planning to test with M1 hardware, but there are several other pieces currently blocking me from running the test suite.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 28

Most upvoted comments

@tisba thanks! Works nice for me as well.

One thing though, is that while it pass on M1, it breaks on Circle CI, whith the following output:

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.

current directory:
/home/circleci/bw_rails/vendor/bundle/ruby/2.6.0/gems/mini_racer-0.5.0.pre/ext/mini_racer_extension
/usr/local/bin/ruby -I /usr/local/lib/ruby/2.6.0 -r
./siteconf20211201-526-162if6l.rb extconf.rb
checking for -lpthread... yes
creating Makefile

current directory:
/home/circleci/bw_rails/vendor/bundle/ruby/2.6.0/gems/mini_racer-0.5.0.pre/ext/mini_racer_extension
make "DESTDIR=" clean

current directory:
/home/circleci/bw_rails/vendor/bundle/ruby/2.6.0/gems/mini_racer-0.5.0.pre/ext/mini_racer_extension
make "DESTDIR="
compiling mini_racer_extension.cc
cc1plus: warning: command-line option ‘-Wimplicit-int’ is valid for C/ObjC but
not for C++
cc1plus: note: unrecognized command-line option ‘-Wno-self-assign’ may have been
intended to silence earlier diagnostics
cc1plus: note: unrecognized command-line option ‘-Wno-parentheses-equality’ may
have been intended to silence earlier diagnostics
cc1plus: note: unrecognized command-line option ‘-Wno-constant-logical-operand’
may have been intended to silence earlier diagnostics
linking shared-object mini_racer_extension.so
g++: error:
/home/circleci/bw_rails/vendor/bundle/ruby/2.6.0/gems/libv8-node-16.10.0.0-x86_64-linux/vendor/v8/x86_64-linux/libv8/obj/libv8_monolith.a:
No such file or directory
make: *** [Makefile:262: mini_racer_extension.so] Error 1

make failed, exit code 2

Gem files will remain installed in
/home/circleci/bw_rails/vendor/bundle/ruby/2.6.0/gems/mini_racer-0.5.0.pre for
inspection.
Results logged to
/home/circleci/bw_rails/vendor/bundle/ruby/2.6.0/extensions/x86_64-linux/2.6.0/mini_racer-0.5.0.pre/gem_make.out

An error occurred while installing mini_racer (0.5.0.pre), and Bundler

I’m not familiar with those, so I’m not sure if there’s an easy workaround?

Edit: would that be related to an obsolete toolchain in the CI image?

From the readme:

Note using v8.h and compiling MiniRacer requires a C++11 standard compiler, more specifically clang 3.5 (or later) or gcc 4.8 (or later).

Quick update related to this issue using mini_racer=0.5.0.pre

I’ve successfully re-run my test on M1 with Docker Desktop with

gem "mini_racer", "0.5.0.pre"
gem "libv8-node", "16.10.0.0"

against these Rubies:

  • 3.0.0, 3.0.1, 3.0.2
  • 2.7.3
  • 2.6.7

They all ran to completion 🥳

So it looks like, we could – once 0.5.0 gets released – add a remark to the readme that 0.4.0 has some issues on aarch and 0.5.0 should be used.

I am a very strong no on any support for EOL Rubies. I don’t support EOL Rubies on any of my projects.

I open to keep old support if we must to avoid a fork @lloeki but would prefer to stay just with supported Rubies.

I can confirm that the rails assets:precompile command works with mini_racer 0.6.0 on an M1 MacBook Air, using Docker Desktop.

I’ve created a seperate issue for the CircleCI problem: #227

Interestingly https://github.com/rubyjs/mini_racer/issues/170 seems also to be resolved. At least I cannot reproduce the problem with this build.

I need a bit more time to make that work against my large private project, but so far this looks very promising!

It first I was confused, because it did resolve the dependency correctly, but I assume you want me to test this with https://github.com/rubyjs/mini_racer/tree/libv8-node-16, right?

I put your .gem file into a local gem repository (created via gem generate_index) and used the inline Gemfile:

gemfile do
  source "https://rubygems.org"

  gem "mini_racer", git: "https://github.com/rubyjs/mini_racer", branch: "libv8-node-16"
  gem "libv8-node", source: "file:///app/repo"
end

The rest of the script is like in the PR description. And it looks good 😃

  • 3.0.0, 3.0.1 ✅
  • 2.7.3 ✅
  • 2.6.7 ✅
  • 2.5.8 ✅

I now have a (manually) cross-compiled libv8-node 16.3.0 gem over here, it works for me but I’d rather not publish it on rubygems yet because I have to persist and automate the host=x86_64/target=aarch64 cross-compiling changes in CI.

If anyone is up to try it, I can provide the gem as well as the small diff of changes for mini_racer to support libv8-node 16.3.0 (I’ll do a PR around shortly)

I’m tracking progress of ARM support at the libv8-node repo. Short status update: cross-compiling to aarch64 on x86_64 is promising and appears OK, but I run into a dumb missing symbol error (v8::V8::SetFlagsFromString(char const*, unsigned long)) when testing.

It’s most probably not. I think the LoadError comes from a failure by Ruby to load the .so with the root cause being the problematic libv8-node on aarch64, it just manifests itself differently than the stack smashing (which loads but then proceeds to burst into flames).