diff --git a/gc.c b/gc.c index d0067e4165..ff6c8a64d1 100644 --- a/gc.c +++ b/gc.c @@ -4426,16 +4426,20 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table) VALUE objid; VALUE final; rb_control_frame_t *cfp; + VALUE *sp; long finished; } saved; + rb_execution_context_t * volatile ec = GET_EC(); #define RESTORE_FINALIZER() (\ ec->cfp = saved.cfp, \ + ec->cfp->sp = saved.sp, \ ec->errinfo = saved.errinfo) saved.errinfo = ec->errinfo; saved.objid = rb_obj_id(obj); saved.cfp = ec->cfp; + saved.sp = ec->cfp->sp; saved.finished = 0; saved.final = Qundef; diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index a577fcb16b..4c4a7f6a27 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -810,6 +810,15 @@ class TestGc < Test::Unit::TestCase obj = nil end end; + + assert_normal_exit "#{<<~"begin;"}\n#{<<~'end;'}", '[Bug #20042]' + begin; + def (f = Object.new).call = nil # missing ID + o = Object.new + ObjectSpace.define_finalizer(o, f) + o = nil + GC.start + end; end def test_object_ids_never_repeat