From: "zonuexe (Kenta USAMI) via ruby-core" Date: 2026-08-24T12:08:37+00:00 Subject: [ruby-core:126481] [Ruby Bug#22260] Ruby::Box: SIGSEGV when calling a method inside an isolated Proc defined at class/module body (RUBY_BOX=1) Issue #22260 has been reported by zonuexe (Kenta USAMI). ---------------------------------------- Bug #22260: Ruby::Box: SIGSEGV when calling a method inside an isolated Proc defined at class/module body (RUBY_BOX=1) https://bugs.ruby-lang.org/issues/22260 * Author: zonuexe (Kenta USAMI) * Status: Open * ruby -v: ruby 4.1.0dev (2026-08-24T10:31:23Z master 042e2bfd39) +PRISM [arm64-darwin25] * Backport: 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- ## Summary Under `RUBY_BOX=1`, any method call inside a Proc isolated by `Ractor.make_shareable` (or `Proc#isolate`) and defined at a class/module body crashes the VM: ```console $ RUBY_BOX=1 ruby -e 'module M; L = Ractor.make_shareable(->(*a){ Rational(*a) }); end; p M::L.call(3, 4)' -e:1: [BUG] Segmentation fault at 0x0000000000000000 $ ruby -e 'module M; L = Ractor.make_shareable(->(*a){ Rational(*a) }); end; p M::L.call(3, 4)' (3/4) ``` The Proc body does not matter (`a.to_s`, `1.zero?`, `String.name` all crash). A Proc defined inside a method body works. No user sub-boxes are involved. Backtrace: `rb_vm_search_method_slowpath` ��� `callable_method_entry_or_negative` ��� `search_method0`, faulting in `RCLASS_EXT_TABLE_LOOKUP_INTERNAL` with `box == NULL` (`box->box_object` sits at offset 0 of `rb_box_t`, hence address 0x0). ## Root cause A TOP/CLASS frame's env stores its box pointer in the SPECVAL slot; that is what `VM_ENV_BOX()` reads and `rb_current_box()` returns via `current_box_on_cfp()`. `env_copy()` (vm.c, called from `proc_isolate_env()`) rebuilds a local env with ```c else { ep[VM_ENV_DATA_INDEX_SPECVAL] = VM_BLOCK_HANDLER_NONE; } ``` so the copy keeps its frame type but loses its box. The first method lookup inside the isolated Proc then dereferences the NULL box. ## Proposed patch Copy the SPECVAL slot through for TOP/CLASS envs (patch attached, with a regression test in test/ruby/test_box.rb): ```c else if (VM_ENV_BOXED_P(src_ep)) { ep[VM_ENV_DATA_INDEX_SPECVAL] = src_ep[VM_ENV_DATA_INDEX_SPECVAL]; } ``` On master (042e2bfd39) the new test segfaults before the patch and passes after it; test_box.rb, test_proc.rb and test_ractor.rb stay green (288 tests, 0 failures). ## Context Hit by the [Rigor](https://github.com/rigortype/rigor) static analyzer, which calls `Ractor.make_shareable`d module-scope lambdas from worker Ractors. With the patch, analyzing the whole Redmine codebase under `RUBY_BOX=1` completes. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/