summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <[email protected]>2023-12-19 17:32:19 +0900
committerKoichi Sasada <[email protected]>2023-12-19 17:59:49 +0900
commitf9a48548cf3ef54fc0a385ccd78c708737055ecc (patch)
tree8212edda0b1ca44868328d2dd39099014a59a78e
parent96e4f42b3d13f37afce1a8c584a56f6d7e98ec23 (diff)
restore the stack pointer on finalizer
When error on finalizer, the exception will be ignored. To restart the code, we need to restore the stack pointer. fix [Bug #20042]
-rw-r--r--gc.c4
-rw-r--r--test/ruby/test_gc.rb9
2 files changed, 13 insertions, 0 deletions
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