检测内存泄漏的工具

10

内存泄漏检测工具(如Purify和Valgrind)是如何工作的?

我该如何设计和实现自己的类似工具?


1
https://dev59.com/PnI-5IYBdhLWcg3w0cKG - stephan
1
你可以先尝试一下我的堆调试器;-) - fredoverflow
我不会将其标记为重复,因为“valgrind”问题是相关的,但“如何实现自己的”是新的。 - Matthieu M.
5个回答

8
这样的工具通常会用自己的代码来“检测”可执行文件。例如,它们会将每个对 malloc()free() 的调用替换为自己的函数,这使得它们可以跟踪每个分配。
在 Visual Studio 中,可以仅使用 C 运行时库和 _CrtDumpMemoryLeaks() 函数系列自动完成此操作。

2
你可以使用工具 - deleaker(如果你是Windows用户)。 - MastAvalons
2
Deleaker - 很酷的工具!支持内存和GDI泄漏等。 - z0r1fan

5

对于基本的泄漏检测,您只需要连接到低级内存分配例程,例如通过修补malloc/free。然后,您可以跟踪所有分配,并在适当的时间,例如在退出之前报告任何未被释放的分配。


3

对于实际工作,Valgrind非常有效。它可以检测无效的读/写操作和内存泄漏。

对于业余项目,您可以创建自己的内存管理模块,以跟踪各种指针分配及其使用情况。如果您长时间没有看到某个内存位置被使用,则可能存在泄漏。


1

1

我正在开发这个工具: Deleaker

当然,显而易见的想法是挂钩所有进行分配和释放的函数。这不仅包括malloc和free,还包括HeapAlloc / HeapFree(如果我们谈论Windows平台),因为现代VC ++版本(VC 6.0之后)只是将malloc / free重定向到winapi的HeapAlloc / HeapFree。

对于每个分配,都会保存一个堆栈和一个对象。在每次释放时,该对象被释放。乍一看,它很简单:只需存储已分配对象的列表,并在释放挂钩上删除对象。

但有些棘手的部分:

  • 速度

您需要维护已分配对象的列表。如果您在每个挂钩函数中添加/删除对象,则进程执行速度太慢。这似乎是此类工具的常见问题。

  • 堆栈跟踪

使用dbghelp.dll函数获取堆栈跟踪需要很长时间。您必须通过手动读取进程内存等方式更快地获取堆栈条目。

  • 误报
一些泄漏是由系统DLL产生的。如果你显示所有泄漏,你会得到大量的泄漏,但用户无法“解决”它:他/她没有访问其源代码的权限,也不能防止执行此代码。这些泄漏无法停止。其中一些是在系统dll入口点进行的单个分配,因此这不是真正的泄漏(一个好问题,到底什么是泄漏?)。如何识别必须显示的那些泄漏?良好的过滤是一个答案。 希望这可以帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接