!htrace
:扩展用于显示一个或多个句柄的堆栈回溯信息
!htrace [Handle [Max_Traces]]
!htrace -enable [Max_Traces]
!htrace -snapshot
!htrace -diff
!htrace -disable
!htrace -?
!htrace
,显示当前的所有句柄信息
使用!htrace 定位句柄内存泄露基本步骤:
!htrace -enable
,启用handle trace,并且创建第一个快照作为初始状态,方便使用 -diff选项!htrace -snapshot
,创建快照,用作-diff选项!htrace -diff
,使用当前状态的信息,和最近一次的快照信息做对比!htrace -disable
,禁用handle trace
下面我们将使用一个简单的demo来分析一下
DWORD WINAPI _tfunc(LPVOID lparam){
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
while (true)
{
CreateEvent(NULL, true, false, NULL);
CreateThread(NULL, 0, _tfunc, NULL, 0, NULL);
Sleep(10000);
}
return 0; return 0;
}
第一步,运行程序,然后break之后启用handle trace
并且使用!htrace
查看一下当前信息,并且创建一下!htrace -snapshot
运行一段时间之后,我们使用!htrace -diff
查看一下handle的变化信息
从这里可以看出,这次比上次快照多了0x02
个handle,分别是NtCreateEvent和ZwCreateThreadEx创建的句柄,然后调用这两个函数的位置分别在0x00007ff77ac61032: test!wmain+0x0000000000000022
和
0x00007ff77ac6104f: test!wmain+0x000000000000003f
,所以此时我们通过lsa
定位源码信息:
此时可以一眼就看到因为我们创建了事件和句柄都没有关闭,到此位置句柄泄露定位完毕。
同时我们也可以使用!handle xx f
查看一下handle的信息
!handle
,列举所有的句柄信息
所以通过上述信息我们可以知道c4
是Event
类型,c0
是Thread
的类型。