When the obj.hash method of an element in a nested Set data structure throws an exception from within Set#flatten, a memory leak occurs.
The reason is that the exception prevents the working data structure allocated by set_do_flatten() from being freed.
-
mruby revision: commit b18a99c
-
build:
rake -m clean all -
file: set-memleak.rb
s = Set[Set[a = Object.new]] class << a def hash 0 / 0 end end s.flatten
-
result with valgrind:
% valgrind --leak-check=full -- build/host/bin/mruby set-memleak.rb ==79222== Memcheck, a memory error detector ==79222== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al. ==79222== Using Valgrind-3.25.1 and LibVEX; rerun with -h for copyright info ==79222== Command: build/host/bin/mruby set-memleak.rb ==79222== trace (most recent call last): [2] set-memleak.rb:9 [1] set-memleak.rb:9:in flatten set-memleak.rb:5:in hash: divided by 0 (ZeroDivisionError) ==79222== ==79222== HEAP SUMMARY: ==79222== in use at exit: 82 bytes in 2 blocks ==79222== total heap usage: 776 allocs, 774 frees, 229,603 bytes allocated ==79222== ==79222== 82 (16 direct, 66 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2 ==79222== at 0x4853371: realloc (vg_replace_malloc.c:1807) ==79222== by 0x27E599: mrb_realloc_simple (gc.c:202) ==79222== by 0x27E599: mrb_realloc (gc.c:216) ==79222== by 0x27E599: mrb_malloc (gc.c:232) ==79222== by 0x27E599: mrb_calloc (gc.c:251) ==79222== by 0x2CFB7E: kh_init_set_val_size (set.c:35) ==79222== by 0x2CFB7E: kh_init_set_val (set.c:35) ==79222== by 0x2CFB7E: set_do_flatten (set.c:1243) ==79222== by 0x2CF950: set_flatten (set.c:1280) ==79222== by 0x2A5ED9: mrb_vm_exec (vm.c:0) ==79222== by 0x2B0D81: mrb_load_exec (parse.y:7342) ==79222== by 0x2B109F: mrb_load_detect_file_cxt (parse.y:7385) ==79222== by 0x260065: main (mruby.c:353) ==79222== ==79222== LEAK SUMMARY: ==79222== definitely lost: 16 bytes in 1 blocks ==79222== indirectly lost: 66 bytes in 1 blocks ==79222== possibly lost: 0 bytes in 0 blocks ==79222== still reachable: 0 bytes in 0 blocks ==79222== suppressed: 0 bytes in 0 blocks ==79222== ==79222== For lists of detected and suppressed errors, rerun with: -s ==79222== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)