зеркало из https://github.com/github/ruby.git
Show exception in finalizer [Feature #17798]
This commit is contained in:
Родитель
63e5f4df38
Коммит
fc4dd45d01
15
gc.c
15
gc.c
|
@ -3987,6 +3987,16 @@ run_single_final(VALUE cmd, VALUE objid)
|
|||
return rb_check_funcall(cmd, idCall, 1, &objid);
|
||||
}
|
||||
|
||||
static void
|
||||
warn_exception_in_finalizer(rb_execution_context_t *ec, VALUE final)
|
||||
{
|
||||
if (final != Qundef) {
|
||||
VALUE errinfo = ec->errinfo;
|
||||
rb_warn("Exception in finalizer %+"PRIsVALUE, final);
|
||||
rb_ec_error_print(ec, errinfo);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
|
||||
{
|
||||
|
@ -3995,6 +4005,7 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
|
|||
volatile struct {
|
||||
VALUE errinfo;
|
||||
VALUE objid;
|
||||
VALUE final;
|
||||
rb_control_frame_t *cfp;
|
||||
long finished;
|
||||
} saved;
|
||||
|
@ -4007,16 +4018,18 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
|
|||
saved.objid = rb_obj_id(obj);
|
||||
saved.cfp = ec->cfp;
|
||||
saved.finished = 0;
|
||||
saved.final = Qundef;
|
||||
|
||||
EC_PUSH_TAG(ec);
|
||||
state = EC_EXEC_TAG();
|
||||
if (state != TAG_NONE) {
|
||||
++saved.finished; /* skip failed finalizer */
|
||||
warn_exception_in_finalizer(ec, ATOMIC_VALUE_EXCHANGE(saved.final, Qundef));
|
||||
}
|
||||
for (i = saved.finished;
|
||||
RESTORE_FINALIZER(), i<RARRAY_LEN(table);
|
||||
saved.finished = ++i) {
|
||||
run_single_final(RARRAY_AREF(table, i), saved.objid);
|
||||
run_single_final(saved.final = RARRAY_AREF(table, i), saved.objid);
|
||||
}
|
||||
EC_POP_TAG();
|
||||
#undef RESTORE_FINALIZER
|
||||
|
|
|
@ -161,6 +161,13 @@ End
|
|||
END
|
||||
end
|
||||
|
||||
def test_exception_in_finalizer
|
||||
assert_in_out_err([], "#{<<~"begin;"}\n#{<<~'end;'}", [], /finalizing \(RuntimeError\)/)
|
||||
begin;
|
||||
ObjectSpace.define_finalizer(Object.new) {raise "finalizing"}
|
||||
end;
|
||||
end
|
||||
|
||||
def test_each_object
|
||||
klass = Class.new
|
||||
new_obj = klass.new
|
||||
|
|
Загрузка…
Ссылка в новой задаче