工具:LeakDiag 可以从微软的FTP进行下载: ftp://ftp.microsoft.com/PSS/Tools/Developer%20Support%20Tools/LeakDiag/
leakdiag125.msi 下载后大约有1.7MB,缺省的安装目录是C:/leakdiag
LeakDiag 目前支持六种类型的泄漏:
Virtual Allocator
Heap Allocator
MPHeap Allocator
COM AllocatorCoTaskMem
COM Private Allocator
C Runtime Allocator
LeakDiag拦截指定内存分配的调用并跟踪各种调用栈,它报告已分配但尚未释放的内存,这一信息允许逐个地排除内存泄露问题,以精确查看哪些组件进行了该分配。使用正确的调试符号,还可以查看分配内存的具体代码行数。
LeakDiag 和常见的内存测试工具不一致的地方是,它使用了微软的Detours 技术,常见的内存测试工具通常都在代码编译或者连接阶段来修改进行一些修改,进而对内存分配释放等操作进行截获。而Microsoft Detours就可以中断原有的执行过程转而执行你提供的detour代码或者是在之前加入一些代码然后继续执行原有代码。看起来就好像是在原有函数的入 口处直接跳转到新代码了,而这是在运行期变更的。
接触一个最简单的例,有如下C代码,memleak.c:
01.
#include <stdio.h>
02.
#include <string.h>
03.
04.
int
main(
void
)
05.
{
06.
char
*p = NULL;
07.
while
(
getc
(stdin))
08.
{
09.
p = (
char
*)
malloc
(1024);
10.
}
11.
}
明眼人一看就知道问题出在哪儿了。
编译好,执行程序。然后在运行leakdiag。我们从进程列表中选出memleak.exe。点击"start" 开始检测,然后我们在memleak.exe的控制台上随便输入些东西,点击一下log按钮记录日志,然后stop 结束。
这时候就会在logs目录下生成一个XML的日志文件了。查看一下文件内容,关键信息如下(在LEAKS下):
1.
<
FRAME
num
=
"0"
dll
=
"ntdll.dll"
function
=
"CsrAllocateCaptureBuffer"
offset
=
"0x36"
filename
=
""
line
=
""
addr
=
"0x7C93EB8E"
/>
2.
<
FRAME
num
=
"1"
dll
=
"kernel32.dll"
function
=
"GetConsoleInputWaitHandle"
offset
=
"0x1DF"
filename
=
""
line
=
""
addr
=
"0x7C8727F8"
/>
3.
<
FRAME
num
=
"2"
dll
=
"kernel32.dll"
function
=
"ReadConsoleA"
offset
=
"0x3B"
filename
=
""
line
=
""
addr
=
"0x7C872A78"
/>
4.
<
FRAME
num
=
"3"
dll
=
"kernel32.dll"
function
=
"ReadFile"
offset
=
"0xA5"
filename
=
""
line
=
""
addr
=
"0x7C8018B7"
/>
5.
<
FRAME
num
=
"4"
dll
=
"memleak.exe"
function
=
""
filename
=
""
line
=
""
addr
=
"0x407f6b"
offset
=
"0x00007F6B"
/>
调用的堆栈及代码地址信息被记录下来了,通过设置options里面的Symbol Search Path,将pdb所在的目录加进去,再次执行,就可以得到具体的代码行数了,如下:
1.
<
FRAME
num
=
"0"
dll
=
"memleak.exe"
function
=
"_heap_alloc_base"
offset
=
"0xC2"
filename
=
"malloc.c"
line
=
"200"
addr
=
"0x403752"
/>
2.
<
FRAME
num
=
"1"
dll
=
"memleak.exe"
function
=
"_heap_alloc_dbg"
offset
=
"0x1A2"
filename
=
"dbgheap.c"
line
=
"378"
addr
=
"0x401362"
/>
3.
<
FRAME
num
=
"2"
dll
=
"memleak.exe"
function
=
"_nh_malloc_dbg"
offset
=
"0x19"
filename
=
"dbgheap.c"
line
=
"248"
addr
=
"0x401169"
/>
4.
<
FRAME
num
=
"3"
dll
=
"memleak.exe"
function
=
"malloc"
offset
=
"0x19"
filename
=
"dbgheap.c"
line
=
"130"
addr
=
"0x4010E9"
/>
5.
<
FRAME
num
=
"4"
dll
=
"memleak.exe"
function
=
"main"
offset
=
"0x76"
filename
=
"c:/working/temp/memleak/main.c"
line
=
"9"
addr
=
"0x401086"
/>
关于detours,参考: http://research.microsoft.com/en-us/projects/detours/