Project

General

Profile

Actions

Bug #21673

closed

Segmentation Fault in IRB when refining `Kernel#puts` using `Module#refine` (Regression since Ruby 3.4)

Bug #21673: Segmentation Fault in IRB when refining `Kernel#puts` using `Module#refine` (Regression since Ruby 3.4)

Added by yokomaru (Yoko Suzuki) 1 day ago. Updated 18 minutes ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [arm64-darwin24]
[ruby-dev:<unknown>]

Description

In the IRB environment running Ruby 3.4 and later, the VM crashes with a Segmentation Fault when a module refining Kernel#puts is defined and puts is subsequently executed. The crash does not occur when the exact same code is executed as a regular Ruby script.

Environment

Reproduced on multiple environments:

macOS 15.5 (Apple Silicon M1, MacBook Pro)
- ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [arm64-darwin24] 
- ruby 3.5.0dev (2025-11-06 master cf4a034d59) +PRISM [arm64-darwin24]
- irb 1.15.3 (also reproduced with 1.13.1)
- Installed via rbenv
Omarhy 3.1.3(Linux 6.17.5-arch1-1)
- ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [x86_64-linux]
- irb 1.15.3
- Installed via mise

This does not occur on: Ruby 3.3.10 + IRB 1.13.1

Steps to Reproduce (Reproduction Script)

The crash reproduces with these steps (on Ruby 3.4+):

  1. Start irb.
    $ irb
    
  2. Define the refinement module for Kernel#puts.
    module Foo
      refine Kernel do
        def puts
        end
      end
    end
    # Explicit 'using Foo' is NOT required
    
  3. Execute puts at the IRB prompt.
    puts # ← Segmentation Fault occurs here
    

Expected Result
As observed in Ruby 3.3.10, the IRB session should continue to operate normally.

Actual Result (Execution Log Excerpt)
The full crash logs (for macOS and Arch Linux) and the macOS crash report are provided in the attached files.

$ irb
irb(main):001* module Foo
irb(main):002*   refine Kernel do
irb(main):003*     def puts
irb(main):004*     end
irb(main):005*   end
irb(main):006> end
=> #<refinement:Kernel@Foo>
irb(main):007> put/Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb/context.rb:636: [BUG] Segmentation fault at 0x0000000000000030
ruby 3.4.7 (2025-10-08 revision 7a5688e2a2) +PRISM [arm64-darwin24]
               puts
-- Crash Report log information --------------------------------------------
   See Crash Report log file in one of the following locations:
     * ~/Library/Logs/DiagnosticReports
     * /Library/Logs/DiagnosticReports
   for more details.
Don't forget to include the above Crash Report log file in bug reports.

-- Control frame information -----------------------------------------------
c:0049 p:---- s:0274 e:000273 CFUNC :public_method
c:0048 p:---- s:0271 e:000270 CFUNC :bind_call
c:0047 p:0221 s:0265 e:000264 METHOD /Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb/context.rb:636
c:0046 p:0034 s:0251 e:000250 METHOD /Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb/context.rb:648
c:0045 p:0010 s:0239 e:000238 BLOCK /Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb/input-method.rb:277
c:0044 p:0024 s:0233 e:000232 METHOD /Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/reline-0.6.2/lib/reline/line_editor.rb:787

<...snip...>

-- Ruby level backtrace information ----------------------------------------
/Users/USER/.rbenv/versions/3.4.7/bin/irb:25:in '<main>'
/Users/USER/.rbenv/versions/3.4.7/bin/irb:25:in 'load'
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/exe/irb:9:in '<top (required)>'
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb.rb:54:in 'start'
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb.rb:173:in 'run'
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb.rb:173:in 'catch'
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb.rb:174:in 'block in run'
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb.rb:193:in 'eval_input'
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/gems/3.4.0/gems/irb-1.15.3/lib/irb.rb:278:in 'each_top_level_statement'
<internal:kernel>:168:in 'loop'

<...snip...>

-- C level backtrace information -------------------------------------------
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_vm_bugreport+0xb6c) [0x102ccdaa8]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_bug_for_fatal_signal+0x100) [0x102b07bfc]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(sigsegv+0x84) [0x102c2e2f4]
/usr/lib/system/libsystem_platform.dylib(_sigtramp+0x38) [0x19e60c624]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_callable_method_entry_with_refinements+0xd8) [0x102caabb4]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_callable_method_entry_with_refinements+0xd8) [0x102caabb4]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(obj_method+0x160) [0x102bcbf74]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_call0_body+0x35c) [0x102cc4b50]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_vm_call_kw+0xc4) [0x102cae300]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_call_cfunc_with_frame_+0xf0) [0x102cbf798]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_exec_core+0x46c8) [0x102ca77f0]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_vm_exec+0x1b4) [0x102ca1fa4]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(invoke_block_from_c_bh+0x36c) [0x102cc7614]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_yield+0xa8) [0x102cafa54]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_ary_each+0x40) [0x102a5b7f8]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_call_cfunc_with_frame_+0xf0) [0x102cbf798]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_exec_core+0x2620) [0x102ca5748]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_vm_exec+0x1b4) [0x102ca1fa4]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(invoke_block_from_c_bh+0x36c) [0x102cc7614]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_yield+0xa8) [0x102cafa54]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_protect+0xb0) [0x102b13918]
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/3.4.0/arm64-darwin24/io/console.bundle(ttymode+0x1e0) [0x102462ab4]
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/3.4.0/arm64-darwin24/io/console.bundle(ttymode) (null):0
/Users/USER/.rbenv/versions/3.4.7/lib/ruby/3.4.0/arm64-darwin24/io/console.bundle(console_raw+0x40) [0x102460ca0]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_call_cfunc_with_frame_+0xf0) [0x102cbf798]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_exec_core+0x2620) [0x102ca5748]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_vm_exec+0x134) [0x102ca1f24]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(invoke_block_from_c_bh+0x36c) [0x102cc7614]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_yield+0xa8) [0x102cafa54]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_ensure+0xac) [0x102b13a70]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_call_cfunc_with_frame_+0xf0) [0x102cbf798]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_exec_core+0x2620) [0x102ca5748]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_vm_exec+0x134) [0x102ca1f24]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(invoke_block_from_c_bh+0x36c) [0x102cc7614]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(catch_i+0x6c) [0x102cc6d50]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_catch_protect+0xbc) [0x102cb1b70]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_f_catch+0x70) [0x102cb2560]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_call_cfunc_with_frame_+0xf0) [0x102cbf798]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_exec_core+0x2620) [0x102ca5748]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_vm_exec+0x1b4) [0x102ca1fa4]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(load_iseq_eval+0x224) [0x102b73b50]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_load_internal+0x84) [0x102b70e8c]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_f_load+0x8c) [0x102b72aa0]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_call_cfunc_with_frame_+0xf0) [0x102cbf798]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(vm_exec_core+0x46c8) [0x102ca77f0]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_vm_exec+0x134) [0x102ca1f24]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(rb_ec_exec_node+0x8c) [0x102b12c14]
/Users/USER/.rbenv/versions/3.4.7/lib/libruby.3.4.dylib(ruby_run_node+0x40) [0x102b12b3c]
/Users/USER/.rbenv/versions/3.4.7/bin/ruby(main+0x68) [0x1022c0618]

Files

backtrace_ruby-3.4.7_macos.txt (111 KB) backtrace_ruby-3.4.7_macos.txt yokomaru (Yoko Suzuki), 11/08/2025 04:39 AM
macos_crash_report_ruby-3.4.7.ips.txt (31.4 KB) macos_crash_report_ruby-3.4.7.ips.txt yokomaru (Yoko Suzuki), 11/08/2025 04:41 AM
backtrace_ruby-3.4.7_omarchy(archlinux).txt (90.4 KB) backtrace_ruby-3.4.7_omarchy(archlinux).txt yokomaru (Yoko Suzuki), 11/08/2025 07:48 AM

Updated by yokomaru (Yoko Suzuki) 1 day ago Actions #1

I sincerely apologize, but I made an error in the entry regarding the second environment's information, so I have corrected it and re-uploaded the backtrace file.

The file has been updated to reflect the correct distribution name.

There are no changes to the other core information, such as the reproduction steps or the error information (Segmentation Fault) at the time of the crash. Thank you for your understanding.

Updated by tompng (tomoya ishida) about 20 hours ago Actions #2

It can be reproduced without IRB

module Foo
  refine Kernel do
    def puts; end
  end
end
method(:puts)

Updated by nobu (Nobuyoshi Nakada) about 11 hours ago · Edited Actions #3

Although I'm not sure why 3.3 didn't crash, probably, since ME owned by a module doesn't have defined_class, it shouldn't be copied to defined_class_ptr?

diff --git a/vm_method.c b/vm_method.c
index 506a2919b77..8b2983e621e 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -2005,7 +2005,12 @@ resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *de
 
         tmp_me = me->def->body.refined.orig_me;
         if (tmp_me) {
-            if (defined_class_ptr) *defined_class_ptr = tmp_me->defined_class;
+            if (!tmp_me->defined_class) {
+                VM_ASSERT_TYPE(tmp_me->owner, T_MODULE);
+            }
+            else if (defined_class_ptr) {
+                *defined_class_ptr = tmp_me->defined_class;
+            }
             return tmp_me;
         }
 

https://github.com/ruby/ruby/pull/15114

Updated by nobu (Nobuyoshi Nakada) about 3 hours ago Actions #4

  • Status changed from Open to Closed

Applied in changeset git|a4dff09be79b52288a47658964d25e5aa84fc960.


[Bug #21673] Fix resolving refined module-defined method

A method defined in a module has no defined_class, use the ICLASS
for it as the defined_class.

Updated by nagachika (Tomoyuki Chikanaga) 18 minutes ago Actions #5

  • Backport changed from 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN to 3.2: REQUIRED, 3.3: REQUIRED, 3.4: REQUIRED

I wasn't able to reproduce the SEGV using the added test code. However, the implemfentation of resolve_refined_method() is the same on every stable branch. I will fill the Backport field with REQUIRED.

Actions

Also available in: PDF Atom