工具: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:
view source
print
?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下):
view source
print
?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所在的目錄加進去,再次執行,就可以得到具體的程式碼數了,如下:
view source
print
?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/