内存泄漏检测工具(如Purify和Valgrind)是如何工作的?
我该如何设计和实现自己的类似工具?
内存泄漏检测工具(如Purify和Valgrind)是如何工作的?
我该如何设计和实现自己的类似工具?
malloc()
和 free()
的调用替换为自己的函数,这使得它们可以跟踪每个分配。_CrtDumpMemoryLeaks()
函数系列自动完成此操作。对于基本的泄漏检测,您只需要连接到低级内存分配例程,例如通过修补malloc/free。然后,您可以跟踪所有分配,并在适当的时间,例如在退出之前报告任何未被释放的分配。
对于实际工作,Valgrind非常有效。它可以检测无效的读/写操作和内存泄漏。
对于业余项目,您可以创建自己的内存管理模块,以跟踪各种指针分配及其使用情况。如果您长时间没有看到某个内存位置被使用,则可能存在泄漏。
您可以寻找一些BSD内存管理/分析工具的实现代码作为参考。例如http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools
我正在开发这个工具: Deleaker。
当然,显而易见的想法是挂钩所有进行分配和释放的函数。这不仅包括malloc和free,还包括HeapAlloc / HeapFree(如果我们谈论Windows平台),因为现代VC ++版本(VC 6.0之后)只是将malloc / free重定向到winapi的HeapAlloc / HeapFree。
对于每个分配,都会保存一个堆栈和一个对象。在每次释放时,该对象被释放。乍一看,它很简单:只需存储已分配对象的列表,并在释放挂钩上删除对象。
但有些棘手的部分:
您需要维护已分配对象的列表。如果您在每个挂钩函数中添加/删除对象,则进程执行速度太慢。这似乎是此类工具的常见问题。
使用dbghelp.dll函数获取堆栈跟踪需要很长时间。您必须通过手动读取进程内存等方式更快地获取堆栈条目。