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]
This commit is contained in:
parent
96e4f42b3d
commit
f9a48548cf
4
gc.c
4
gc.c
@ -4426,16 +4426,20 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
|
|||||||
VALUE objid;
|
VALUE objid;
|
||||||
VALUE final;
|
VALUE final;
|
||||||
rb_control_frame_t *cfp;
|
rb_control_frame_t *cfp;
|
||||||
|
VALUE *sp;
|
||||||
long finished;
|
long finished;
|
||||||
} saved;
|
} saved;
|
||||||
|
|
||||||
rb_execution_context_t * volatile ec = GET_EC();
|
rb_execution_context_t * volatile ec = GET_EC();
|
||||||
#define RESTORE_FINALIZER() (\
|
#define RESTORE_FINALIZER() (\
|
||||||
ec->cfp = saved.cfp, \
|
ec->cfp = saved.cfp, \
|
||||||
|
ec->cfp->sp = saved.sp, \
|
||||||
ec->errinfo = saved.errinfo)
|
ec->errinfo = saved.errinfo)
|
||||||
|
|
||||||
saved.errinfo = ec->errinfo;
|
saved.errinfo = ec->errinfo;
|
||||||
saved.objid = rb_obj_id(obj);
|
saved.objid = rb_obj_id(obj);
|
||||||
saved.cfp = ec->cfp;
|
saved.cfp = ec->cfp;
|
||||||
|
saved.sp = ec->cfp->sp;
|
||||||
saved.finished = 0;
|
saved.finished = 0;
|
||||||
saved.final = Qundef;
|
saved.final = Qundef;
|
||||||
|
|
||||||
|
@ -810,6 +810,15 @@ class TestGc < Test::Unit::TestCase
|
|||||||
obj = nil
|
obj = nil
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
def test_object_ids_never_repeat
|
def test_object_ids_never_repeat
|
||||||
|
Loading…
x
Reference in New Issue
Block a user