【问题标题】:Using valgrind to find a memory leak in the mysql c++ clientmysql c++客户端使用valgrind查找内存泄漏
【发布时间】:2012-08-04 17:52:03
【问题描述】:

我正在使用 valgrind 来尝试追踪内存泄漏是从 mysql 分发的 mysql c++ 客户端。

在示例 (resultset.cpp) 和我自己的程序中,都有一个 56 字节的块没有被释放。在我自己的程序中,我追踪到了对 mysql 客户端的调用。

这是我运行测试时的结果:

valgrind --leak-check=full --show-reachable=yes ./my-executable

==29858== Memcheck, a memory error detector
==29858== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==29858== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==29858== Command: ./my-executable
==29858==
==29858==
==29858== HEAP SUMMARY:
==29858==     in use at exit: 56 bytes in 1 blocks
==29858==   total heap usage: 693 allocs, 692 frees, 308,667 bytes allocated
==29858==
==29858== 56 bytes in 1 blocks are still reachable in loss record 1 of 1
==29858==    at 0x4C284A8: malloc (vg_replace_malloc.c:236)
==29858==    by 0x400D334: _dl_map_object_deps (dl-deps.c:506)
==29858==    by 0x4013652: dl_open_worker (dl-open.c:291)
==29858==    by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==29858==    by 0x4012FF9: _dl_open (dl-open.c:583)
==29858==    by 0x7077BCF: do_dlopen (dl-libc.c:86)
==29858==    by 0x400E9C5: _dl_catch_error (dl-error.c:178)
==29858==    by 0x7077D26: __libc_dlopen_mode (dl-libc.c:47)
==29858==    by 0x72E5FEB: pthread_cancel_init (unwind-forcedunwind.c:53)
==29858==    by 0x72E614B: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
==29858==    by 0x72E408F: __pthread_unwind (unwind.c:130)
==29858==    by 0x72DDEB4: pthread_exit (pthreadP.h:265)
==29858==
==29858== LEAK SUMMARY:
==29858==    definitely lost: 0 bytes in 0 blocks
==29858==    indirectly lost: 0 bytes in 0 blocks
==29858==      possibly lost: 0 bytes in 0 blocks
==29858==    still reachable: 56 bytes in 1 blocks
==29858==         suppressed: 0 bytes in 0 blocks
==29858==
==29858== For counts of detected and suppressed errors, rerun with: -v
==29858== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 8 from 6)

我对此有几个问题:

  1. 我应该如何解释 --show-reachable 块?
  2. 该块对我尝试将错误归零有用吗?
  3. 如果块没有用,valgrind 是否有另一种机制可以帮助我追踪泄漏?
  4. 如果没有,是否有其他工具(希望是 linux 上的 OSS)来帮助我缩小范围?

提前谢谢..

更新:这是我在我的系统上找到的用于定义 pthread_exit 的代码。我不确定这是被调用的实际来源。但是,如果是这样,谁能解释可能出了什么问题?

void
pthread_exit (void *retval)
{
    /*  specific to PTHREAD_TO_WINTHREAD  */

    ExitThread ((DWORD) ((size_t) retval));  /*  thread becomes signalled so its death can be waited upon  */
    /*NOTREACHED*/
    assert (0); return;  /*  void fnc; can't return an error code  */
}

【问题讨论】:

    标签: c++ linux memory-leaks valgrind memory-leak-detector


    【解决方案1】:

    Reachable 只是意味着当程序退出时,块有一个有效的指针在范围内引用它们,这表明程序没有在退出时显式释放所有内容,因为它依赖于底层操作系统来这样做。您应该寻找的是 lost 块,其中的内存块丢失了对它们的所有引用并且无法再被释放。

    因此,这 56 个字节可能是在 main 中分配的,但并未明确释放它们。您发布的内容没有显示内存泄漏。它显示 main 释放所有内容,但 main 分配的内容除外,因为 main 假定当它死时,所有内存都将被内核回收。

    具体来说,它是 pthread(在 main 中)做出这个假设(这是一个有效的假设,在过去 15 年多的生产中发现的所有东西都差不多)。释放在退出时仍然具有有效引用的块的需要是一个有争议的点,但对于这个特定的问题,所有需要提到的是做出了假设。

    编辑

    实际上pthread_exit() 没有在退出时清理某些东西,但正如解释的那样,它可能不需要(或者很可能不能)一旦达到那个点。

    【讨论】:

    • 谢谢蒂姆。这绝对有帮助。你对我如何找到没有明确释放内存的代码行有什么建议吗?你知道有什么工具可以帮助你做到这一点吗?
    • @Homer6 它实际上是 pthread 做的,没有什么可以修复的(除非你想深入研究 pthread_exit(),寻找它,找到它,明确地释放它).. 但那只能修复它在你的机器上:)
    • 谢谢蒂姆。我已经发布了 pthread_exit 的定义(或者我认为的定义)。对可能发生的事情有任何想法吗?
    • @AdrianCornish 正确,这不是必需的。这里有一些关于在退出时明确释放每个块的相当冗长的讨论(在“我应该还是不应该?”的背景下)并且意见差异很大。在这种情况下,pthread 本身会做出假设。我通常会释放我分配的所有块,只是出于偏好。
    • @Homer6 看看 Valgrind 给你的输出,从 by 0x72DDEB4: pthread_exit (pthreadP.h:265) 开始,然后向后工作。对malloc() 的未释放调用实际上是由/ 在by 0x400D334: _dl_map_object_deps (dl-deps.c:506) 发起的
    猜你喜欢
    • 2011-07-05
    • 1970-01-01
    • 2020-03-31
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    相关资源
    最近更新 更多