From 11286ac479807d7e259cd8347cab2ab516e2565a Mon Sep 17 00:00:00 2001 From: Peter Zhu Date: Fri, 5 Jan 2024 17:14:16 -0500 Subject: [PATCH] Fix memory leak in autoload_data If the autoload_data has autoload_const and the autoload_data is freed before the autoload_const, then the autoload_data will leak. This commit changes it so that when the autoload_data is freed, it will clear the whole linked list of autoload_const so that the autoload_data can be safely freed. 1000.times do |i| str = "foo#{i}".freeze autoload(:"B#{i}", str) autoload(:"C#{i}", str) end Reports leaked memory with the macOS leaks tool: 12 ruby 0x1006398a4 rb_f_autoload + 96 load.c:1524 11 ruby 0x100639710 rb_mod_autoload + 112 load.c:1460 10 ruby 0x10080a914 rb_autoload_str + 224 variable.c:2666 9 ruby 0x1007c3308 rb_mutex_synchronize + 56 thread_sync.c:637 8 ruby 0x1005acb24 rb_ensure + 312 eval.c:1009 7 ruby 0x10080aac8 autoload_synchronized + 204 variable.c:2630 6 ruby 0x10080f8bc autoload_feature_lookup_or_create + 76 variable.c:2578 5 ruby 0x1005c29a4 rb_data_typed_object_zalloc + 232 gc.c:3186 4 ruby 0x1005c2774 ruby_xcalloc + 32 gc.c:14440 3 ruby 0x1005cddf4 ruby_xcalloc_body + 56 gc.c:12878 2 ruby 0x1005cde7c objspace_xcalloc + 124 gc.c:12871 1 ruby 0x1005c1990 calloc1 + 28 gc.c:1906 0 libsystem_malloc.dylib 0x18b2ebb78 _malloc_zone_calloc_instrumented_or_legacy + 100 --- variable.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/variable.c b/variable.c index bb53d15f25..7b4beb9f9a 100644 --- a/variable.c +++ b/variable.c @@ -2460,10 +2460,12 @@ autoload_data_free(void *ptr) { struct autoload_data *p = ptr; - // We may leak some memory at VM shutdown time, no big deal...? - if (ccan_list_empty(&p->constants)) { - ruby_xfree(p); + struct autoload_const *autoload_const, *next; + ccan_list_for_each_safe(&p->constants, autoload_const, next, cnode) { + ccan_list_del_init(&autoload_const->cnode); } + + ruby_xfree(p); } static size_t