首页 > 解决方案 > 解决 valgrind“可能丢失”的内存泄漏

问题描述

我在解释和调试一个 C 程序的 valgrind 输出时遇到了麻烦,我刚刚从一个在线课程 (nand2tetris) 中完成,该课程现在按预期运行。这是源代码的链接:https ://github.com/salario/nand2tetris/blob/master/assembler.c

这是 valgrind 的输出,显示可能丢失的内存泄漏消息。我使用这个命令编译:cc -g -o assembler assembler.c

$ valgrind --leak-check=full ./assembler Pong.asm
==35574== Memcheck, a memory error detector
==35574== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==35574== Using Valgrind-3.16.0.GIT and LibVEX; rerun with -h for copyright info
==35574== Command: ./assembler Pong.asm
==35574== 
==35574== 
==35574== HEAP SUMMARY:
==35574==     in use at exit: 13,932 bytes in 159 blocks
==35574==   total heap usage: 1,096 allocs, 937 frees, 137,988 bytes allocated
==35574== 
==35574== 24 bytes in 1 blocks are possibly lost in loss record 6 of 37
==35574==    at 0x1002B5E51: malloc_zone_calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==35574==    by 0x100877541: NXMapInsert (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x100877625: _NXMapRehash(_NXMapTable*) (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x10087757C: NXMapInsert (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x10087723D: _mapStrHash(_NXMapTable*, void const*) (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x100876FFC: _getObjc2ProtocolList(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x10087596E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1008862D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1001AE5A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==35574==    by 0x1001AE746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==35574==    by 0x10044FAD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==35574==    by 0x100874DAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==35574== 
==35574== 264 bytes in 3 blocks are possibly lost in loss record 30 of 37
==35574==    at 0x1002B5C90: calloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==35574==    by 0x100875049: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1008862D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1001AE5A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==35574==    by 0x1001AE746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==35574==    by 0x10044FAD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==35574==    by 0x100874DAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1003D1F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==35574==    by 0x1003DE0E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==35574==    by 0x1002C1790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==35574==    by 0x1001C41E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==35574==    by 0x1001C45ED: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==35574== 
==35574== 2,064 bytes in 1 blocks are possibly lost in loss record 36 of 37
==35574==    at 0x1002B58AA: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==35574==    by 0x1008770B5: getProtocol(char const*) (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x10087596E: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1008862D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1001AE5A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==35574==    by 0x1001AE746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==35574==    by 0x10044FAD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==35574==    by 0x100874DAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1003D1F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==35574==    by 0x1003DE0E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==35574==    by 0x1002C1790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==35574==    by 0x1001C41E2: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==35574== 
==35574== 2,064 bytes in 1 blocks are possibly lost in loss record 37 of 37
==35574==    at 0x1002B58AA: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD-36f444c/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==35574==    by 0x10087801E: NXMapRemove (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x100877EA5: search_method_list(method_list_t const*, objc_selector*) (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1008760DD: _getObjc2MessageRefs(header_info const*, unsigned long*) (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1008862D0: unmap_image (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1001AE5A5: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==35574==    by 0x1001AE746: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==35574==    by 0x10044FAD0: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==35574==    by 0x100874DAF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==35574==    by 0x1003D1F38: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==35574==    by 0x1003DE0E7: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==35574==    by 0x1002C1790: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==35574== 
==35574== LEAK SUMMARY:
==35574==    definitely lost: 0 bytes in 0 blocks
==35574==    indirectly lost: 0 bytes in 0 blocks
==35574==      possibly lost: 4,416 bytes in 6 blocks
==35574==    still reachable: 9,516 bytes in 153 blocks
==35574==         suppressed: 0 bytes in 0 blocks
==35574== Reachable blocks (those to which a pointer was found) are not shown.
==35574== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==35574== 
==35574== For lists of detected and suppressed errors, rerun with: -s
==35574== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 4 from 4)

我已经阅读了 valgrind 的文档,并且尝试了对源代码的一系列不同更改,但似乎无法解决这些问题。如果有人可以通过查看此错误和来源并让我知道您是否可以发现可能的问题,我将不胜感激。

此外,我尝试了不同的推荐 valgrind 标志,但无法弄清楚如何让输出显示源文件中的行号。此外,所有可能丢失的内存错误详细信息都没有引用我的任何函数或文件,因此调试起来特别具有挑战性。

标签: cmemory-leaksvalgrind

解决方案


这些内存泄漏来自运行时,例如/usr/lib/system/libdispatch.dylib, /usr/lib/libSystem.B.dylib, /usr/lib/dyld.

我在 linux ( valgrind --leak-check=full ./a.out Pong.asm) 上运行了你的程序:

==102140== Memcheck, a memory error detector
==102140== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==102140== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==102140== Command: ./a.out Pong.asm
==102140== 
==102140== 
==102140== HEAP SUMMARY:
==102140==     in use at exit: 0 bytes in 0 blocks
==102140==   total heap usage: 927 allocs, 927 frees, 121,200 bytes allocated
==102140== 
==102140== All heap blocks were freed -- no leaks are possible
==102140== 
==102140== For lists of detected and suppressed errors, rerun with: -s
==102140== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

您的程序中没有内存泄漏,只有加载程序/运行时泄漏内存。


推荐阅读