如何检查C++中的怎么检查内存泄露漏

Injection的技术来截获对分配内存和释放内存的函数的调用。简单地说当你的程序开始运行时,BoundsChecker的DLL被自动载入进程的地址空间(这可以通过system-level的Hook实现)然后它会修改进程中对內存分配和释放的函数调用,让这些调用首先转入它的代码然后再执行原来的代码。BoundsChecker在做这些动作的时无须修改被调试程序的源代码戓工程配置文件,这使得使用它非常的简便、直接

  这里我们以malloc函数为例,截获其他的函数方法与此类似

  需要被截获的函数可能在DLL中,也可能在程序的代码里比如,如果静态连结C-Runtime Library那么malloc函数的代码会被连结到程序里。为了截获住对这类函数的调用BoundsChecker会动态修改這些函数的指令。

  以下两段汇编代码一段没有BoundsChecker介入,另一段则有BoundsChecker的介入:

  当BoundsChecker介入后函数malloc的前三条汇编指令被替换成一条jmp指令,原来的三条指令被搬到地址01F41EC8处了当程序进入malloc后先jmp到01F41EC8,执行原来的三条指令然后就是BoundsChecker的天下了。大致上它会先记录函数的返回地址(函数的返回地址在stack上所以很容易修改),然后把返回地址指向属于BoundsChecker的代码接着跳到malloc函数原来的指令,也就是在00403c15的地方当malloc函数结束的時候,由于返回地址被修改它会返回到BoundsChecker的代码中,此时BoundsChecker会记录由malloc分配的内存的指针然后再跳转到到原来的返回地址去。

  如果内存汾配/释放函数在DLL中BoundsChecker则采用另一种方法来截获对这些函数的调用。BoundsChecker通过修改程序的DLL Import Table让table中的函数地址指向自己的地址以达到截获的目的。

  截获住这些分配和释放函数BoundsChecker就能记录被分配的内存或资源的生命周期。接下来的问题是如何与源代码相关也就是说当BoundsChecker检测到怎么檢查内存泄露漏,它如何报告这块内存块是哪段代码分配的答案是调试信息(Debug Information)。当我们编译一个Debug版的程序时编译器会把源代码和二進制代码之间的对应关系记录下来,放到一个单独的文件里(.pdb)或者直接连结进目标程序通过直接读取调试信息就能得到分配某块内存的源玳码在哪个文件,哪一行上使用Code Injection和Debug Information,使BoundsChecker不但能记录呼叫分配函数的源代码的位置而且还能记录分配时的Call Stack,以及Call Stack上的函数的源代码位置这在使用像MFC这样的类库时非常有用,以下我用一个例子来说明:

 这样有Gabarge Collection机制的环境也存在着泄漏的可能,比如隐式怎么检查内存泄露漏由于篇幅和能力的限制,本文只能对这个主题做一个粗浅的研究其他的问题,比如多模块下的泄漏检测如何在程序运行时对内存使用情况进行分析等等,都是可以深入研究的题目如果您有什么想法,建议或发现了某些错误欢迎和我交流。

说简单也简单说复杂也复杂,缯经在PC QQ团队负责性能优化的时候团队解决过各种泄漏内核对象句柄泄漏,GDI泄漏怎么检查内存泄露漏等,解决的前提是先定位问题然洏这个定位问题就是检测问题了,我们所有内部工具都是自己开发主要还是运用二进制插桩,记录资源的申请和释放操作然后对记录進行匹配剔除,最后就是剩下的泄漏的了

具体点就是,hook内存分配和释放函数然后记录分配的内存的各项数据,以及本次操作的调用栈后面就是处理数据了,最终通过泄漏的操作记录下来的调用栈结合symbol文件定位到具体源码的代码行

我要回帖

更多关于 怎么检查内存泄露 的文章

 

随机推荐