From e59dd7094f281e3167fc8fe29ab0e92e7b66027a Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 12 Jan 2024 11:30:36 -0500 Subject: [PATCH] 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: ': 12 miniruby 0x10286ec50 ivar_set + 140 variable.c:1850 11 miniruby 0x102876afc generic_ivar_set + 136 variable.c:1668 --- gc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gc.c b/gc.c index 0e4dadbdd0..6245e2083b 100644 --- a/gc.c +++ b/gc.c @@ -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;