Have ast live longer in ISeq.compile_file to fix GC stress crash

Previously, live range of `ast_value` ended on the call right before
rb_ast_dispose(), which led to premature collection and use-after-free.

We observed this crashing on -O3, -DVM_CHECK_MODE, with GCC 11.4.0 on
Ubuntu.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
This commit is contained in:
Alan Wu 2025-03-11 13:14:13 -04:00 committed by Takashi Kokubun
parent 5cc4398297
commit 31502b0d85
2 changed files with 7 additions and 0 deletions

1
iseq.c
View file

@ -1749,6 +1749,7 @@ iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
1, NULL, 0, ISEQ_TYPE_TOP, &option,
Qnil));
rb_ast_dispose(ast);
RB_GC_GUARD(ast_value);
rb_vm_pop_frame(ec);
RB_GC_GUARD(v);

View file

@ -919,4 +919,10 @@ class TestISeq < Test::Unit::TestCase
assert_predicate(status, :success?)
end
end
def test_compile_empty_under_gc_stress
EnvUtil.under_gc_stress do
RubyVM::InstructionSequence.compile_file(File::NULL)
end
end
end