(1) gc_verify_internal_consistency() use barrier locking
    for consistency while `during_gc == true` at the end
    of the sweep on `RGENGC_CHECK_MODE >= 2`.
(2) `rb_objspace_reachable_objects_from()` is called without
    VM synchronization and it checks `during_gc != true`.

So (1) and (2) causes BUG because of `during_gc == true`.
To prevent this error, wait for VM barrier on `during_gc == false`
and introduce VM locking on `rb_objspace_reachable_objects_from()`.

http://ci.rvm.jp/results/trunk-asserts@phosphorus-docker/3830088
This commit is contained in:
Koichi Sasada 2022-02-14 16:10:18 +09:00
Родитель 838031170c
Коммит 76e594d515
1 изменённых файлов: 22 добавлений и 14 удалений

16
gc.c
Просмотреть файл

@ -5722,10 +5722,6 @@ gc_sweep_finish(rb_objspace_t *objspace)
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_SWEEP, 0);
gc_mode_transition(objspace, gc_mode_none);
#if RGENGC_CHECK_MODE >= 2
gc_verify_internal_consistency(objspace);
#endif
}
static int
@ -9340,6 +9336,14 @@ gc_exit(rb_objspace_t *objspace, enum gc_enter_event event, unsigned int *lock_l
mjit_gc_exit_hook();
gc_exit_clock(objspace, event);
RB_VM_LOCK_LEAVE_LEV(lock_lev);
#if RGENGC_CHECK_MODE >= 2
if (event == gc_enter_event_sweep_continue && gc_mode(objspace) == gc_mode_none) {
GC_ASSERT(!during_gc);
// sweep finished
gc_verify_internal_consistency(objspace);
}
#endif
}
static void *
@ -11226,6 +11230,8 @@ rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *
{
rb_objspace_t *objspace = &rb_objspace;
RB_VM_LOCK_ENTER();
{
if (during_gc) rb_bug("rb_objspace_reachable_objects_from() is not supported while during_gc == true");
if (is_markable_object(objspace, obj)) {
@ -11240,6 +11246,8 @@ rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *
cr->mfd = prev_mfd;
}
}
RB_VM_LOCK_LEAVE();
}
struct root_objects_data {
const char *category;