【问题标题】:Debugging memory leak issues without any tool无需任何工具即可调试内存泄漏问题
【发布时间】:2014-04-14 12:29:48
【问题描述】:

采访者 - 如果您没有工具来检查您将如何检测内存泄漏问题?

答案 - 我将阅读代码,看看我分配的所有内存是否已在代码本身中被我释放。

面试官不满意。还有其他方法吗?

【问题讨论】:

  • 自己编写(即自定义分配器,可将一段时间内未完成的分配报告到日志或其他报告接收器)。

标签: c memory-management


【解决方案1】:

对于下面定义的所有实现,需要为malloc() 和free() 函数编写包装器。

  1. 为简单起见,请跟踪 malloc() 和 free() 的计数。如果不相等,则说明存在内存泄漏。

  2. 更好的版本是跟踪地址 malloc()'ed 和 free()'ed,这样您就可以识别哪些地址是 malloc()'ed 但不是 free()'ed。但这同样也无济于事,因为您无法将地址与源代码相关联,尤其是当您拥有大量源代码时,这将成为一个挑战。

  3. 因此,您可以在此处再添加一项功能。例如,我为 FreeBSD Kernel 编写了一个类似的工具,您可以修改 malloc() 调用来存储模块/文件信息(给每个模块/文件一个否,您可以在某些标题中#define 它),@ 987654325@ 的函数调用导致此 malloc() 并将其存储在数据结构中,以及每当调用 malloc() 或 free() 时的上述信息。使用malloc() 返回的地址与free() 匹配。因此,当它们发生内存泄漏时,您可以获得关于哪些地址没有在哪个文件中free() 的信息,以及(通过stack trace)调用的确切函数来精确定位它。

这个工具的工作方式是,在崩溃时,我曾经得到一个核心转储。我在内核内存空间中定义了全局变量(我在其中收集数据的数据结构),我可以使用gdb 访问它并检索信息。

编辑:

最近在调试 linux 内核中的内存泄漏时,我遇到了这个名为 kmemleak 的工具,它实现了我在上面第 3 点中描述的类似算法。在此处阅读Basic Algorithm 部分:https://www.kernel.org/doc/Documentation/kmemleak.txt

【讨论】:

    【解决方案2】:

    当我必须真正做到这一点时,我的反应是构建工具...一个调试堆层,包裹在 C 堆周围,以及用于切换代码以针对这些调用运行而不是运行的宏直接访问普通堆库。该层包括一些用于检测数组边界违规的栅栏逻辑,一些用于监控堆在做什么的工具,可选的一些记录究竟是谁分配和释放了每个块......

    当然,另一种方法是“分而治之”。构建单元测试以尝试缩小导致泄漏的操作,然后进一步细分该代码。

    根据“无工具”的含义,核心转储有时也很有用;例如,查看堆的内容可能会告诉您泄漏了什么。

    等等……

    【讨论】:

    • 参考您的最后一行..您如何查看核心转储中堆的内容?
    • 您需要了解该语言如何获取和管理堆空间。这是一种接近汇编程序级别的调试方法。
    • 如果没有失败,如何在程序结束时获取核心转储?
    • 在崩溃时生成核心转储。例如,错误的内存取消引用、取消引用不属于进程的地址等。
    • 没错,这就是我所知道的,那么当发生内存泄漏时如何生成核心转储?程序结束或即将结束后在哪里可以看到堆的内容?
    猜你喜欢
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2012-07-06
    • 2016-07-28
    相关资源
    最近更新 更多