|
From: Mika L. <mli...@pp...> - 2008-11-09 11:51:51
Attachments:
leakcheck.diff
leak-test.c
|
Hi all, Some programs implement custom memory allocators or object caches, which cache deallocated memory blocks and recycle them within the program. While memcheck provides some tools for describing custom memory allocators, leak checking does not produce very accurate information if the custom allocator or object cache is based on malloc (as is often the case). The attached patch makes a few small modifications to the memcheck leak checking code, allowing more accurate leak information. The patch allows the VALGRIND_MALLOCLIKE_BLOCK macro to be used on a memory block that is nested within another memory block. This makes it possible to describe custom allocators and object caches, which get blocks of memory from malloc, deal them (or parts of them) out to clients, and keep around some deleted blocks for possible reuse. Here's how the changes work. In mc_leakcheck.c: 1) The sort rule in lc_compar() function is modified so that shadow blocks having the same start address are sorted smallest first. 2) A rule is added to find_shadow_for() function so that, in case of nested blocks, it always returns the shadow block with the smallest size. Cost is still O(log(n)) as binary search is used as before. 3) The sanity check in do_detect_memory_leaks() is modified to allow nested shadow blocks. It will still complain about blocks that overlap only partially. The simple attached leak-test.c program demonstrates, how the patch improves leak check ouput. The program forgets to dellocate a memory block allocated in function part2(). The block has been recycled via the freelist by the custom allocator. Output with unmodified valgrind (no function wrappers) shows the place of original allocation as line 47 of function part1(): ==5986== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==5986== at 0x400801E: malloc (vg_replace_malloc.c:207) ==5986== by 0x80483BE: myalloc (leak-test.c:10) ==5986== by 0x8048403: part1 (leak-test.c:47) ==5986== by 0x8048485: main (leak-test.c:67) Output with patched valgrind and function wrappers: ==5980== 4 (0 direct, 4 indirect) bytes in 1 blocks are definitely lost in loss record 1 of 3 ==5980== at 0x8048584: myalloc (leak-test.c:30) ==5980== by 0x80486AA: part2 (leak-test.c:59) ==5980== by 0x80486E0: main (leak-test.c:68) The second version accurately pinpoints line 59 in function part2() as the culprit. The attached patch is made against the current SVN head (3.x version). I've ran the regression tests and did not get any new failures compared to unmodified valgrind. I hope you find this patch useful and consider it for inclusion in valgrind. Br, Mika Liljeberg |
|
From: Mika L. <mik...@we...> - 2008-11-09 11:51:52
Attachments:
leakcheck.diff
leak-test.c
|
Hi all, Some programs implement custom memory allocators or object caches, which cache deallocated memory blocks and recycle them within the program. While memcheck provides some tools for describing custom memory allocators, leak checking does not produce very accurate information if the custom allocator or object cache is based on malloc (as is often the case). The attached patch makes a few small modifications to the memcheck leak checking code, allowing more accurate leak information. The patch allows the VALGRIND_MALLOCLIKE_BLOCK macro to be used on a memory block that is nested within another memory block. This makes it possible to describe custom allocators and object caches, which get blocks of memory from malloc, deal them (or parts of them) out to clients, and keep around some deleted blocks for possible reuse. Here's how the changes work. In mc_leakcheck.c: 1) The sort rule in lc_compar() function is modified so that shadow blocks having the same start address are sorted smallest first. 2) A rule is added to find_shadow_for() function so that, in case of nested blocks, it always returns the shadow block with the smallest size. Cost is still O(log(n)) as binary search is used as before. 3) The sanity check in do_detect_memory_leaks() is modified to allow nested shadow blocks. It will still complain about blocks that overlap only partially. The simple attached leak-test.c program demonstrates, how the patch improves leak check ouput. The program forgets to dellocate a memory block allocated in function part2(). The block has been recycled via the freelist by the custom allocator. Output with unmodified valgrind (no function wrappers) shows the place of original allocation as line 47 of function part1(): ==5986== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2 ==5986== at 0x400801E: malloc (vg_replace_malloc.c:207) ==5986== by 0x80483BE: myalloc (leak-test.c:10) ==5986== by 0x8048403: part1 (leak-test.c:47) ==5986== by 0x8048485: main (leak-test.c:67) Output with patched valgrind and function wrappers: ==5980== 4 (0 direct, 4 indirect) bytes in 1 blocks are definitely lost in loss record 1 of 3 ==5980== at 0x8048584: myalloc (leak-test.c:30) ==5980== by 0x80486AA: part2 (leak-test.c:59) ==5980== by 0x80486E0: main (leak-test.c:68) The second version accurately pinpoints line 59 in function part2() as the culprit. The attached patch is made against the current SVN head (3.x version). I've ran the regression tests and did not get any new failures compared to unmodified valgrind. I hope you find this patch useful and consider it for inclusion in valgrind. Br, Mika Liljeberg -- Mika Liljeberg <mik...@we...> |