如purify和valgrind等内存泄漏检测工具如何工作?
如何设计和实施我自己的工具?
答案 0 :(得分:8)
此类工具通常 instrument 可以使用自己的代码执行。例如,他们用自己的函数替换每个malloc()
和free()
的调用,这样就可以跟踪每个分配。
在Visual Studio中,这可以使用C运行时库使用_CrtDumpMemoryLeaks()
答案 1 :(得分:5)
对于基本的泄漏检测,您只需要挂钩到低级别的内存分配例程,例如:通过修补malloc / free。然后,您跟踪所有分配,然后报告任何未在适当时间点释放的分配,例如,就在退出之前。
答案 2 :(得分:3)
对于实际工作,valgrind工作得很好。它检测到无效的读/写和内存泄漏。
对于爱好项目,您可以创建自己的内存管理模块,跟踪各种指针分配及其用法。如果您没有看到长时间使用某个mem位置,则可能是泄漏。
答案 3 :(得分:1)
您可以查找一些内存管理/分析工具的BSD实现,以获取代码示例。例如http://code.google.com/p/google-perftools/wiki/GooglePerformanceTools
答案 4 :(得分:1)
我正在开发此工具:Deleaker。
当然,显而易见的想法是挂钩所有执行分配和解除分配的功能。这不仅仅是malloc和free,而是HeapAlloc / HeapFree(如果我们谈论的是Windows平台),因为现代VC ++版本(在VC 6.0之后)只是将malloc / free重定向到winapi的HeapAlloc / HeapFree。
对于每个分配,保存堆栈并保存对象。在每次释放时,对象都被释放。乍一看,它非常简单:只需存储已分配对象的列表并删除释放钩子上的对象。
但是有一些棘手的部分:
您需要维护已分配对象的列表。如果在每个挂钩函数中添加/删除对象,则该进程正在执行toooo slooow。这似乎是这类工具的常见问题。
使用dbghelp.dll函数获取堆栈跟踪需要花费大量时间。您必须更快地获得堆栈条目:例如通过手动读取进程内存。
系统DLL会产生一些泄漏。如果你展示了所有这些,你就会遇到大量泄漏,但用户无法“解决”它:他/她无法访问其源代码,也无法阻止执行此代码。要阻止这种泄漏是不可能的。其中一些是系统dll入口点的单一分配,所以它不是真正的泄漏(一个好问题,什么是泄漏?)。如何识别必须显示的泄漏?一个好的过滤就是答案。
希望这有帮助。