无需任何工具即可调试内存泄漏问题

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

回答 – 我将读取代码并查看我分配的所有内存是否已由代码本身释放。

面试官不满意。 有没有其他方法可以这样做?

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

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

  2. 一个更好的版本是跟踪地址malloc()’ed&free()’这样你可以识别哪些地址是malloc()’ed但不是free()’ed。 但是,这也无济于事,因为你无法将地址与源代码联系起来,特别是当你拥有大量的源代码时,这将成为一个挑战。

  3. 所以在这里,您可以添加一个function。 例如,我为FreeBSD Kernel编写了一个类似的工具,你可以修改malloc ()调用来存储模块/文件信息(给每个模块/文件一个no,你可以在某个头文件中定义它), stack trace函数调用导致这个malloc ()并将其存储在数据结构中,只要调用malloc ()或free (),就会将其存储在上面的信息中。 使用malloc ()返回的地址与free ()匹配。 因此,当它们的内存泄漏时,您可以获得有关哪些地址不在哪个地址中的信息,在哪个文件中,通过stack trace调用的确切函数是什么来指向它。

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

编辑:

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

当我必须真正做到这一点时,我的回答是构建工具……一个调试堆层,包裹在C堆中,以及宏来切换代码以针对这些调用运行而不是直接访问正常的堆库。 该层包括一些用于检测数组边界违规的fencepost逻辑,一些用于监视堆正在执行操作的工具,可选地记录了确切分配和释放每个块的人员…

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

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

等等….