bootsnap: ibf_dump_object_unsupported […] T_NONE (NotImplementedError)
See: Ruby upstream issue https://bugs.ruby-lang.org/issues/19419 See: Repo with reproduction case https://github.com/tisba/bootsnap-ruby-crash
Steps to reproduce
I’m having a hard time to produce a minimal version that reliably reproduces this error. Locally, with a Gemfile just containing aws-sdk-ec2, nokogiri and bootsnap I have seen it too, but cannot reproduce that reliably on my local machine yet. It seems to happen on a slightly more regular basis in our GH Action CI run, but also not 100% of the time.
According to the trace (see below) the NotImplementedError happens when loading clients_api.rb from the AWS SDK. Note that clients_api.rb is a MASSIVE file with >20,000 LOC. Maybe the size is (part of) the problem?
Is there something I can do to provide more useful information to debug this issue?
Expected behavior
It should not crash.
Actual behavior
It crashes.
System configuration
Bootsnap version: 1.16.0
Ruby version: 3.2.0, 3.2.1 (on aarch64, x86)
Rails version: 7.0.4.2 (not relevant)
Backtrace
In our CI it fails when we do a sanity check of the Rails app via RAILS_ENV=production bundle exec rails runner 'puts "Hello from #{Rails.env}!"':
/home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/compile_cache/iseq.rb:42:in `to_binary': ibf_dump_object_unsupported: 0x00007f11b8efff58 [0 ] T_NONE (NotImplementedError)
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/compile_cache/iseq.rb:42:in `input_to_storage'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/compile_cache/iseq.rb:60:in `fetch'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/compile_cache/iseq.rb:60:in `fetch'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/compile_cache/iseq.rb:85:in `load_iseq'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/aws-sdk-ec2-1.364.0/lib/aws-sdk-ec2.rb:15:in `require_relative'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/aws-sdk-ec2-1.364.0/lib/aws-sdk-ec2.rb:15:in `<main>'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from /opt/hostedtoolcache/Ruby/3.2.0/x64/lib/ruby/gems/3.2.0/gems/bundler-2.4.3/lib/bundler/runtime.rb:60:in `block (2 levels) in require'
from /opt/hostedtoolcache/Ruby/3.2.0/x64/lib/ruby/gems/3.2.0/gems/bundler-2.4.3/lib/bundler/runtime.rb:55:in `each'
from /opt/hostedtoolcache/Ruby/3.2.0/x64/lib/ruby/gems/3.2.0/gems/bundler-2.4.3/lib/bundler/runtime.rb:55:in `block in require'
from /opt/hostedtoolcache/Ruby/3.2.0/x64/lib/ruby/gems/3.2.0/gems/bundler-2.4.3/lib/bundler/runtime.rb:44:in `each'
from /opt/hostedtoolcache/Ruby/3.2.0/x64/lib/ruby/gems/3.2.0/gems/bundler-2.4.3/lib/bundler/runtime.rb:44:in `require'
from /opt/hostedtoolcache/Ruby/3.2.0/x64/lib/ruby/gems/3.2.0/gems/bundler-2.4.3/lib/bundler.rb:195:in `require'
from /home/runner/work/foo/foo/config/application.rb:13:in `<main>'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/railties-7.0.4.2/lib/rails/command/actions.rb:22:in `require_application!'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/railties-7.0.4.2/lib/rails/command/actions.rb:14:in `require_application_and_environment!'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/railties-7.0.4.2/lib/rails/commands/runner/runner_command.rb:33:in `perform'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/thor-1.2.1/lib/thor/command.rb:27:in `run'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/thor-1.2.1/lib/thor/invocation.rb:127:in `invoke_command'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/thor-1.2.1/lib/thor.rb:392:in `dispatch'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/railties-7.0.4.2/lib/rails/command/base.rb:87:in `perform'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/railties-7.0.4.2/lib/rails/command.rb:48:in `invoke'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/railties-7.0.4.2/lib/rails/commands.rb:18:in `<main>'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from /home/runner/work/foo/foo/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.16.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:32:in `require'
from bin/rails:5:in `<main>'
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 13
- Comments: 26 (14 by maintainers)
Commits related to this issue
- Remove ibf_dumper's WB_PROTECTED status It doesn't have the right write barriers in place. For example, there is rb_mark_set(dump->global_buffer.obj_table); in the mark function, but there is n... — committed to XrXr/ruby by XrXr a year ago
- Remove ibf_dumper's WB_PROTECTED status It doesn't have the right write barriers in place. For example, there is rb_mark_set(dump->global_buffer.obj_table); in the mark function, but there is n... — committed to ruby/ruby by XrXr a year ago
- merge revision(s) 86de48e9f69b665ba9ffb5bdc5a181a3adb1a7b8: [Backport #19419] Remove ibf_dumper's WB_PROTECTED status It doesn't have the right write barriers in place. For example, there is ... — committed to nurse/ruby by nurse a year ago
- merge revision(s) 86de48e9f69b665ba9ffb5bdc5a181a3adb1a7b8: [Backport #19419] Remove ibf_dumper's WB_PROTECTED status It doesn't have the right write barriers in place. For example, there is ... — committed to ruby/ruby by nagachika a year ago
Report submitted upstream: https://bugs.ruby-lang.org/issues/19419
Ok, so Alan removed the write barrier and marked the patch as needing a backport, so this should be fixed in Ruby 3.2.2.
Unfortunately there’s not much bootsnap can do to work around this bug. On your end you may want to do some dirty hack such as:
I’ll close this as there isn’t much to do now.
I don’t think it’s related to Nokogiri, if I replace it by
rexmlin the Gemfile I do get GC issues (a bit different):Yes. What is happening is that one reference isn’t properly marked, so when gc trigger the slot is recycled. If the slot is empty you’ll get that
T_NONEerror, but if it’s used by another object you can get weird NoMethodError like yours.At this stage what could help:
C Level Backtracebut withgc.stress = true. This is very slow, but would properly pinpoint where the bug is.