Pass more T_DATA to obj_free() under RUBY_FREE_AT_EXIT

T_DATA without a pointer or free function may still have ivars set on
them that need to be freed. The following leaked generic ivars for
example:

    converter = Encoding::Converter.allocate
    converter.instance_variable_set(:@foo, 1)

    STACK OF 1 INSTANCE OF 'ROOT LEAK: <malloc in objspace_xmalloc0>':
    <snip>
    12  miniruby    0x10286ec50 ivar_set + 140  variable.c:1850
    11  miniruby    0x102876afc generic_ivar_set + 136  variable.c:1668
This commit is contained in:
Alan Wu 2024-01-12 11:30:36 -05:00
parent 0462b1b350
commit e59dd7094f

2
gc.c
View File

@ -4684,7 +4684,7 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
void *poisoned = asan_unpoison_object_temporary(vp);
switch (BUILTIN_TYPE(vp)) {
case T_DATA:
if (!DATA_PTR(p) || !RANY(p)->as.data.dfree) break;
if (!rb_free_at_exit && (!DATA_PTR(p) || !RANY(p)->as.data.dfree)) break;
if (rb_obj_is_thread(vp)) break;
if (rb_obj_is_mutex(vp)) break;
if (rb_obj_is_fiber(vp)) break;