内存泄漏调试

如果没有跟踪工具,有哪些检测/调试内存泄漏的技术?

拦截分配和释放内存的所有函数(取决于平台,列表可能如下所示:malloc,calloc,realloc,strdup,getcwd,free),除了执行这些函数最初执行的操作外,还可以保存有关调用的信息。 ,在动态增长的全局数组中,可能受multithreading程序的同步原语保护。

此信息可能包括函数名称,请求的内存量,成功分配的块的地址,堆栈跟踪,可以让您确定调用者是什么,等等。 在free()中,从数组中删除相应的元素(如果没有,则将错误的指针传递给free,这也是一个很好的早期检测错误)。 当程序结束时,转储数组的其余元素 – 它们将是泄漏的块。 不要忘记分别在main()之前和之后分配和释放资源的全局对象。 要正确计算这些资源,您需要在最后一个全局对象被销毁之后转储剩余的资源,因此可能需要对编译器运行时进行小规模的修改

  1. 检查你的循环
  2. 看看你在哪里分配变量 – 你有没有取消分配它们?
  3. 尝试使用一小部分可疑代码重现泄漏。
  4. MAKE跟踪工具 – 您始终可以登录到文件。

一种可能性是编译代码并在可以利用内置工具的系统上执行它(例如Solaris上的libumem或Linux上的libcfunction )

分而治之是最好的方法。 如果您已经系统地编写了代码,那么调用代码的子集应该非常容易。 你最好的办法是一遍又一遍地执行每段代码,看看你的内存使用量是否稳步攀升,如果没有继续下一段代码。

另外,关于内存泄漏的维基百科文章在参考部分中有几个很好的链接,用于检测不同系统(窗口,macos,linux等)的内存泄漏

关于SO的类似问题:

  • C的内存泄漏检测器
  • 当你完成所有错误时,追踪内存泄漏的策略

除了其他人提到的手动检查技术之外,您还应该考虑使用代码分析工具,例如valgrind

从他们的网站介绍:

Valgrind是一个屡获殊荣的用于构建动态分析工具的仪器框架。 Valgrind工具可以自动检测许多内存管理和线程错误,并详细介绍您的程序。 您还可以使用Valgrind构建新工具。

Valgrind发行版目前包括六个生产质量工具:内存错误检测器,两个线程错误检测器,一个缓存和分支预测分析器,一个调用图生成缓存分析器和一个堆分析器。 它还包括两个实验工具:堆/堆栈/全局arrays溢出检测器和SimPoint基本块矢量生成器。 它运行在以下平台上:X86 / Linux,AMD64 / Linux,PPC32 / Linux,PPC64 / Linux和X86 / Darwin(Mac OS X)。

我使用了memtrace http://www.fpx.de/fp/Software/MemTrace/ http://sourceforge.net/projects/memtrace/

如果有任何泄漏,您可能需要调用统计函数来打印输出。 最好的方法是在执行模块或代码之前和之后调用此统计函数。 *警告* Memtrace非常友好,允许内存覆盖/双重释放。 它可以检测到这些exception并优雅地避免任何崩溃。