Add potential missing GC guard in iseq_data_to_ary

The iseq object might be optimized away by the compiler in iseq_data_to_ary
because we mainly only use the iseq_body. With MMTk, this crash occasionally
happens:

    TestIseqLoad#test_stressful_roundtrip [test/-ext-/iseq_load/test_iseq_load.rb:20]:
    pid 106677 killed by SIGSEGV (signal 11) (core dumped)
    | -:10: [BUG] Segmentation fault at 0x0000000000f1410c
    | ruby 4.1.0dev (2026-01-05T23:31:16Z master 5d26a2aeea) +PRISM +GC[mmtk] [x86_64-linux]
    |
    | -- Control frame information -----------------------------------------------
    | c:0005 p:---- s:0022 e:000021 l:y b:---- CFUNC  :to_a
    | c:0004 p:0039 s:0018 e:000017 l:y b:0001 METHOD -:10
    | c:0003 p:0013 s:0010 e:000009 l:y b:0001 METHOD -:16
    | c:0002 p:0054 s:0006 e:000005 l:n b:---- EVAL   -:26 [FINISH]
    | c:0001 p:0000 s:0003 E:0003a0 l:y b:---- DUMMY  [FINISH]
    |
    | -- Ruby level backtrace information ----------------------------------------
    | -:26:in '<main>'
    | -:16:in 'test_bug8543'
    | -:10:in 'assert_iseq_roundtrip'
    | -:10:in 'to_a'
    |
    | -- Threading information ---------------------------------------------------
    | Total ractor count: 1
    | Ruby thread count for this ractor: 1
    |
    | -- Machine register context ------------------------------------------------
    |  RIP: 0x000055b581f866f5 RBP: 0x0000000000000000 RSP: 0x00007ffccce2ffe0
    |  RAX: 0x00000200ffee2b08 RBX: 0x0000000000f1410c RCX: 0x0000000000000000
    |  RDX: 0x000000000010c7f2 RDI: 0x00000200ffee2b08 RSI: 0x00000200ffee2b08
    |   R8: 0x0000000000000004  R9: 0x00000c0803ffb8ac R10: 0x00007fe9074c0cc8
    |  R11: 0x0000000000000246 R12: 0x0000000000000000 R13: 0x0000000000000001
    |  R14: 0x0000000000000001 R15: 0x00000200ffee2208 EFL: 0x0000000000010246
    |
    | -- C level backtrace information -------------------------------------------
    | ruby(rb_print_backtrace+0x14) [0x55b582119a9f] vm_dump.c:1105
    | ruby(rb_vm_bugreport) vm_dump.c:1450
    | ruby(rb_bug_for_fatal_signal+0x102) [0x55b582409072] error.c:1131
    | ruby(sigsegv+0x46) [0x55b582051bf6] signal.c:948
    | /lib/x86_64-linux-gnu/libc.so.6(0x7fe907645330) [0x7fe907645330]
    | ruby(iseq_data_to_ary+0xe5) [0x55b581f866f5] iseq.c:3380
    | ruby(iseq_data_to_ary+0x6b2) [0x55b581f86cc2] iseq.c:3470
    | ruby(vm_call_cfunc_with_frame_+0x10d) [0x55b5820e4a0d] vm_insnhelper.c:3902
This commit is contained in:
Peter Zhu 2026-01-05 20:25:52 -05:00
parent 58fb95af36
commit 5c24f4081d
Notes: git 2026-01-06 22:17:05 +00:00

4
iseq.c
View File

@ -3345,6 +3345,7 @@ iseq_type_id(enum rb_iseq_type type)
static VALUE
iseq_data_to_ary(const rb_iseq_t *iseq)
{
VALUE iseq_value = (VALUE)iseq;
unsigned int i;
long l;
const struct rb_iseq_constant_body *const iseq_body = ISEQ_BODY(iseq);
@ -3677,6 +3678,9 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
rb_ary_push(val, params);
rb_ary_push(val, exception);
rb_ary_push(val, body);
RB_GC_GUARD(iseq_value);
return val;
}