mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Show exception in finalizer [Feature #17798]
This commit is contained in:
parent
63e5f4df38
commit
fc4dd45d01
Notes:
git
2021-07-23 12:01:42 +09:00
2 changed files with 21 additions and 1 deletions
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);
|
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
|
static void
|
||||||
run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
|
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 {
|
volatile struct {
|
||||||
VALUE errinfo;
|
VALUE errinfo;
|
||||||
VALUE objid;
|
VALUE objid;
|
||||||
|
VALUE final;
|
||||||
rb_control_frame_t *cfp;
|
rb_control_frame_t *cfp;
|
||||||
long finished;
|
long finished;
|
||||||
} saved;
|
} saved;
|
||||||
|
@ -4007,16 +4018,18 @@ run_finalizer(rb_objspace_t *objspace, VALUE obj, VALUE table)
|
||||||
saved.objid = rb_obj_id(obj);
|
saved.objid = rb_obj_id(obj);
|
||||||
saved.cfp = ec->cfp;
|
saved.cfp = ec->cfp;
|
||||||
saved.finished = 0;
|
saved.finished = 0;
|
||||||
|
saved.final = Qundef;
|
||||||
|
|
||||||
EC_PUSH_TAG(ec);
|
EC_PUSH_TAG(ec);
|
||||||
state = EC_EXEC_TAG();
|
state = EC_EXEC_TAG();
|
||||||
if (state != TAG_NONE) {
|
if (state != TAG_NONE) {
|
||||||
++saved.finished; /* skip failed finalizer */
|
++saved.finished; /* skip failed finalizer */
|
||||||
|
warn_exception_in_finalizer(ec, ATOMIC_VALUE_EXCHANGE(saved.final, Qundef));
|
||||||
}
|
}
|
||||||
for (i = saved.finished;
|
for (i = saved.finished;
|
||||||
RESTORE_FINALIZER(), i<RARRAY_LEN(table);
|
RESTORE_FINALIZER(), i<RARRAY_LEN(table);
|
||||||
saved.finished = ++i) {
|
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();
|
EC_POP_TAG();
|
||||||
#undef RESTORE_FINALIZER
|
#undef RESTORE_FINALIZER
|
||||||
|
|
|
@ -161,6 +161,13 @@ End
|
||||||
END
|
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
|
def test_each_object
|
||||||
klass = Class.new
|
klass = Class.new
|
||||||
new_obj = klass.new
|
new_obj = klass.new
|
||||||
|
|
Loading…
Add table
Reference in a new issue