Injection的技术来截获对分配内存和释放内存的函数的调用。简单地说当你的程序开始运行时,BoundsChecker的DLL被自动载入进程的地址空间(这可以通过system-level的Hook实现)然后它会修改进程中对內存分配和释放的函数调用,让这些调用首先转入它的代码然后再执行原来的代码。BoundsChecker在做这些动作的时无须修改被调试程序的源代码戓工程配置文件,这使得使用它非常的简便、直接
这里我们以malloc函数为例,截获其他的函数方法与此类似
需要被截获的函数可能在DLL中,也可能在程序的代码里比如,如果静态连结C-Runtime Library那么malloc函数的代码会被连结到程序里。为了截获住对这类函数的调用BoundsChecker会动态修改這些函数的指令。
以下两段汇编代码一段没有BoundsChecker介入,另一段则有BoundsChecker的介入:
如果内存汾配/释放函数在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机制的环境也存在着泄漏的可能,比如隐式怎么检查内存泄露漏由于篇幅和能力的限制,本文只能对这个主题做一个粗浅的研究其他的问题,比如多模块下的泄漏检测如何在程序运行时对内存使用情况进行分析等等,都是可以深入研究的题目如果您有什么想法,建议或发现了某些错误欢迎和我交流。 |
具体点就是,hook内存分配和释放函数然后记录分配的内存的各项数据,以及本次操作的调用栈后面就是处理数据了,最终通过泄漏的操作记录下来的调用栈结合symbol文件定位到具体源码的代码行