dearblue · GitHub

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)

Read the original on github.com ↗