确定内存泄漏是否为误报

问题描述 投票:0回答:1

我有一个用 C++ 编写的简单程序,它构建在以下配置中:

  1. 使用/与
    libstdc++
  2. 连接
  3. 使用/与
    libc++
  4. 连接

我使用 valgrind 运行两个版本,如下所示:

valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=test_program.log -v ./test_program

libstdc++
版本运行并不会导致内存泄漏:

==
== HEAP SUMMARY:
==     in use at exit: 0 bytes in 0 blocks
==   total heap usage: 24,813,106 allocs, 24,813,106 frees, 51,325,970,073 bytes allocated
==
== All heap blocks were freed -- no leaks are possible
==
== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

但是,当运行

libc++
时,它显示内存泄漏:

==434036== HEAP SUMMARY:
==434036==     in use at exit: 16 bytes in 1 blocks
==434036==   total heap usage: 317,709,577 allocs, 317,709,576 frees, 645,827,127,171 bytes allocated
==434036==
==434036== Searching for pointers to 1 not-freed blocks
==434036== Checked 401,408 bytes
==434036==
==434036== 16 bytes in 1 blocks are still reachable in loss record 1 of 1
==434036==    at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==434036==    by 0x49A365F: ??? (in /usr/lib/llvm-14/lib/libc++abi.so.1.0)
==434036==    by 0x49A24E9: __cxa_get_globals (in /usr/lib/llvm-14/lib/libc++abi.so.1.0)
==434036==    by 0x49A53F6: __cxa_throw (in /usr/lib/llvm-14/lib/libc++abi.so.1.0)
==434036==    by 0x2EE7B3: goal::details::special_node<double>::value() const (in workspace/goal/goal_test)
==434036==    by 0x2DC349: goal::details::caller_node<double>::value() const (in workspace/goal/goal_test)
==434036==    by 0x50AC40: double goal::details::arg_node<double>::process<main_node<double> > const&) (in workspace/goal/goal_test)
==434036==    by 0x45A79C: bool execute_test_base<double>() (in workspace/goal/goal_test)
==434036==    by 0x2322A0: main (in workspace/goal/goal_test)
==434036==
==434036== LEAK SUMMARY:
==434036==    definitely lost: 0 bytes in 0 blocks
==434036==    indirectly lost: 0 bytes in 0 blocks
==434036==      possibly lost: 0 bytes in 0 blocks
==434036==    still reachable: 16 bytes in 1 blocks
==434036==         suppressed: 0 bytes in 0 blocks
==434036==
==434036== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

我有两个进一步的程序版本:

  1. libstdc++
    一起使用/链接 与
    ASAN/LSAN/UBSAN/TSAN
  2. libc++
    一起使用/链接 与
    ASAN/LSAN/UBSAN/TSAN

运行它们时,它们都不会触发消毒剂错误或警告。

使用的编译器:

  1. g++-13 (Ubuntu 13.1.0-8ubuntu1~22.04) 13.1.0
  2. clang版本20.0.0git

仅当与 libc++ 链接时才在两个编译器上观察到 valgrind 泄漏。


问题: valgrind 的泄漏是否可能是误报?还可以采取哪些措施来验证其合法性?

c++ memory-leaks valgrind address-sanitizer
1个回答
0
投票

简单的规则。不要欺骗自己,认为可能存在误报。这几乎总是只是一厢情愿和确认偏见。

Valgrind memcheck 确实会产生一些误报,但数量很少。泄漏检测是一项“简单”的工作,因此误报率基本上为零。

Memcheck 可以比消毒剂更好地进行泄漏检测,因为它可以完整地查看来宾 exe 的执行情况,从第一条指令到最后一条指令。我不是消毒剂专家,但我想消毒剂代码只能在第一个全局构造函数执行时启动。

正如评论中所说,如果你的 exe 抛出一个以 std::terminate 结尾的异常,那么像 atexit cleanup 这样的事情就不会被执行。仅当 exe 执行干净退出时,泄漏检测才有意义。

© www.soinside.com 2019 - 2024. All rights reserved.