使用windbg定位句柄泄漏

运行windbg,打开要调试的程序,并使其跑起来;此时你查看任务管理器中的句柄信息,会发现相应进程句柄一直在增加。

windbg用ctrl+break命令中断进程运行,用!htrace -enable命令开启句柄检测。htrace提供了进行句柄相关检测的命令,可查看windbg帮助。

0:001> !htrace -enable
Handle tracing enabled.
Handle tracing information snapshot successfully taken.

然后用g命令让程序运行。

操作一段时间程序再次中断进程,使用!htrace -snapshot命令,获得此时进程句柄的快照。并再次让程序运行。

0:001> !htrace -snapshot
Handle tracing information snapshot successfully taken.

第三次中断进程运行,我们再使用!htrace -diff命令获得当前句柄状态与第4步snapshot快照句柄的差异。

Handle = 0x00000110 - OPEN
Thread ID = 0x00000624, Process ID = 0x00001bcc

0x772655b4: ntdll!ZwCreateEvent+0x0000000c
0x751c7926: KERNELBASE!CreateEventExW+0x0000006e
0x751c7976: KERNELBASE!CreateEventW+0x00000027
0x0103145e: My!CMyDlg::OnBnClickedOk+0x0000000e
0x77add375: mfc90u!CCmdTarget::OnCmdMsg+0x00000124
0x77acb1e5: mfc90u!CDialog::OnCmdMsg+0x0000001d
0x77aafefe: mfc90u!CWnd::OnCommand+0x00000092
0x77aaf701: mfc90u!CWnd::OnWndMsg+0x00000066
0x77aaf674: mfc90u!CWnd::WindowProc+0x00000024
0x77aae29a: mfc90u!AfxCallWndProc+0x000000a3
0x77aae526: mfc90u!AfxWndProc+0x00000037
0x77aac1dd: mfc90u!AfxWndProcBase+0x00000056

我们使用lsa 传递指定位置对应的代码,lsa My!CMyDlg::OnBnClickedOk+0x0000000e。到这里,我们就找到了泄露句柄的函数。

0:001> lsa My!CMyDlg::OnBnClickedOk+0x0000000e
   158:     // TODO: Add your control notification handler code here
   159: //    OnOK();
   160:     HANDLE hEvent2;
   161:     hEvent2 = CreateEvent(NULL,TRUE,TRUE,NULL);
>  162: }