diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2024-01-12 11:30:36 -0500 |
---|---|---|
committer | Alan Wu <XrXr@users.noreply.github.com> | 2024-01-12 13:28:36 -0500 |
commit | e59dd7094f281e3167fc8fe29ab0e92e7b66027a (patch) | |
tree | b72f2b6039879fa6b3259b0c57cac6e71015b74d /gc.c | |
parent | 0462b1b350b0f86ce4cfebc195fe0f24005d28f4 (diff) |
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
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -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; |