windbg !htrace 学习总结
生活随笔
收集整理的這篇文章主要介紹了
windbg !htrace 学习总结
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
windbg-!htrace(跟蹤句柄泄漏)
http://blog.csdn.net/hgy413/article/details/7631187!htrace
!htrace(Handle Trace) 擴展用于顯示一個或多個句柄的堆棧回溯信息。
直接用!htrace -?可以看到簡單使用說明:
0:000> !htrace -? !htrace [handle [max_traces]] !htrace -enable [max_traces] !htrace -disable !htrace -snapshot !htrace -diff
Handle
指定要顯示堆棧回溯的句柄。如果Handle 為0 或者省略,則顯示進程中所有句柄的堆棧回溯。
Process
(僅內核模式) 指定要顯示句柄的進程。如果Process 為0或者省略,則使用當前進程。用戶模式下總是使用當前進程。
Max_Traces
指定要顯示的堆棧回溯的最大層數。用戶模式下如果省略該參數,則顯示目標進程中的所有堆棧回溯。
-enable
(僅用戶模式) 啟用句柄跟蹤,并且為-diff 選項使用的初始狀態產生第一次句柄信息的快照。
-snapshot
(僅用戶模式) 抓取當前的句柄信息的快照用作-diff 選項的初始狀態。.
-diff
(僅用戶模式) 將當前的句柄信息和上一次句柄快照的信息進行對比。顯示所有仍然打開的句柄。
-disable
(僅用戶模式;僅Windows Server 2003和之后的系統) 禁止句柄跟蹤。在Windows XP中,只有結束目標進程才能禁用句柄跟蹤。
-?
在調試器命令窗口中顯示一些簡要的幫助文本。
首先需要用!htrace -enable來告訴操作系統啟用棧回溯(這是前提)
!htrace -snapshot !htrace -diff 0:000> !htrace -enable Handle tracing enabled. Handle tracing information snapshot successfully taken.
可以看到,-enable是一個兩步操作,首先,啟動棧回溯(Handle tracing enabled),
然后,它根據句柄來抓取進程當前狀態的快照(Handle tracing information snapshot successfully taken.)在棧回溯被啟用后,windows將立即開始記錄所有的句柄創建調用和句柄刪除調用,在下一次抓取快照時(-snapshot),!htrace將向操作系統查詢所有句柄
創建調用和句柄刪除調用的棧回溯,并且把它們顯示出來,
這時直接用!htrace會輸出以下內容:
0:001> !htrace -------------------------------------- Handle = 0x000007bc - CLOSE Thread ID = 0x000014fc, Process ID = 0x000013f0 0x7c8135dd: kernel32!GetLongPathNameW+0x00000249 0x7854287c: MSVCR90!_check_manifest+0x0000009c 0x78542c22: MSVCR90!__CRTDLL_INIT+0x0000008e 0x78542d5e: MSVCR90!_CRTDLL_INIT+0x0000001e 0x7c92118a: ntdll!LdrpCallInitRoutine+0x00000014 0x7c93b5d2: ntdll!LdrpRunInitializeRoutines+0x00000344 0x7c93fbdc: ntdll!LdrpInitializeProcess+0x0000114b 0x7c93fad7: ntdll!_LdrpInitialize+0x00000183 0x7c92e457: ntdll!KiUserApcDispatcher+0x00000007 -------------------------------------- Handle = 0x000007bc - OPEN Thread ID = 0x000014fc, Process ID = 0x000013f0 0x7c80ef97: kernel32!FindFirstFileW+0x00000016 0x7c8135c5: kernel32!GetLongPathNameW+0x00000231 0x7854287c: MSVCR90!_check_manifest+0x0000009c 0x78542c22: MSVCR90!__CRTDLL_INIT+0x0000008e 0x78542d5e: MSVCR90!_CRTDLL_INIT+0x0000001e 0x7c92118a: ntdll!LdrpCallInitRoutine+0x00000014 0x7c93b5d2: ntdll!LdrpRunInitializeRoutines+0x00000344 0x7c93fbdc: ntdll!LdrpInitializeProcess+0x0000114b 0x7c93fad7: ntdll!_LdrpInitialize+0x00000183 -------------------------------------- Handle = 0x000007c0 - CLOSE Thread ID = 0x000014fc, Process ID = 0x000013f0 0x7c8135dd: kernel32!GetLongPathNameW+0x00000249 0x7854287c: MSVCR90!_check_manifest+0x0000009c 0x78542c22: MSVCR90!__CRTDLL_INIT+0x0000008e 0x78542d5e: MSVCR90!_CRTDLL_INIT+0x0000001e 0x7c92118a: ntdll!LdrpCallInitRoutine+0x00000014 0x7c93b5d2: ntdll!LdrpRunInitializeRoutines+0x000003 .........................
0:000> !htrace -diff Handle tracing information snapshot successfully taken. 0xfa new stack traces since the previous snapshot. Ignoring handles that were already closed... Outstanding handles opened since the previous snapshot: -------------------------------------- Handle = 0x000005b0 - OPEN Thread ID = 0x000007f4, Process ID = 0x000013f0 0x00401657: test1!CServer::GetToken+0x00000047 0x0040136f: test1!CServer::GetSID+0x0000001f 0x004010de: test1!ThreadWorker+0x0000007e 0x7c80b729: kernel32!BaseThreadStart+0x00000037 -------------------------------------- Handle = 0x000005b4 - OPEN Thread ID = 0x00000c34, Process ID = 0x000013f0 0x00401657: test1!CServer::GetToken+0x00000047 0x0040136f: test1!CServer::GetSID+0x0000001f 0x004010de: test1!ThreadWorker+0x0000007e 0x7c80b729: kernel32!BaseThreadStart+0x00000037 -------------------------------------- Handle = 0x000005b8 - OPEN Thread ID = 0x00001650, Process ID = 0x000013f0 0x00401657: test1!CServer::GetToken+0x00000047
很明顯了,我們看到在GetToken中有句柄未關閉,所以在使用!htrace時采用的步驟一般是:
1. 在重現泄漏問題之前,啟用句柄跟蹤(!htrace -enable)
2.執行重現過程,并且讓進程句柄泄漏
3.通過!htrace -diff來找出有問題的棧
自己寫了下DML方便使用:
.printf "\n\nfor trace handle leak\n" .block { as ${/v:ScriptName} c:\\cmdtree\\script\\User-Mode\\traceHandle.txt } .printf /D "<link cmd=\"!htrace -enable;ad ${/v:ScriptName};$$><${ScriptName}\">trace handle :<col fg=\"changed\"bg=\"wbg\"><b>snap-enable</b></col></link>\n\n" .printf /D "<link cmd=\"!htrace -snapshot;ad ${/v:ScriptName};$$><${ScriptName}\">trace handle :<col fg=\"changed\"bg=\"wbg\"><b>snap-snapshot</b></col></link>\n\n" .printf /D "<link cmd=\".echo you should get snapshot more than twice!!!!!!!!!!!!!!!!!!!!!!!!!;!htrace -diff;ad ${/v:ScriptName};$$><${ScriptName}\"\n\n>trace handle :<col fg=\"changed\"bg=\"wbg\"><b>diff</b></col></link>\n\n"
========
用windbg的!htrace定位句柄泄露 ?
http://chenkegarfield.blog.163.com/blog/static/62330008201192122745542/
http://blogs.msdn.com/b/ntdebugging/archive/2007/09/14/talkbackvideo-understanding-handle-leaks-and-how-to-use-htrace-to-find-them.aspx
鏈接是老外的一篇文章,簡單介紹了如何運用windbg中的htrace定位程序中的句柄泄露問題,同時附有一個教學視頻。下面是對應的中文解釋。
1、用c++寫一個句柄泄露的樣例程序:
#include <windows.h>
void fun1(void);
void fun2(void);
void fun3(void);
void fun4(void);
int main(int argc, char* argv[])
{
? ? ? while(1)
? ? ? {
? ? ? ? ? ? fun1();
? ? ? ? ? ? fun2();
? ? ? ? ? ? Sleep(100);
? ? ? }
? ? ? return 0;
}
void fun1(void)
{
? ? ? fun3();
}
void fun2(void)
{
? ? ? fun4();
}
void fun3(void)
{
? ? ? HANDLE hEvent;
? ? ? hEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
? ? ? CloseHandle(hEvent);
}
void fun4(void)
{
? ? ? HANDLE hEvent2;
? ? ? hEvent2 = CreateEvent(NULL,TRUE,TRUE,NULL);//這里只打開但是沒關閉句柄
}
代碼非常簡單,明眼人一看就能看出哪里有問題,那么程序編譯后用windbg怎么調出來呢?
2、windbg調試
1)找到windbg安裝目錄下的gflags.exe工具,該工具可用來打開windows自帶的一些調試選項,具體gflags.exe的詳細使用可以查看windbg幫助;
用windbg的!htrace定位句柄泄露 - chenkegarfield - chenkegarfield的博客用windbg的!htrace定位句柄泄露 - chenkegarfield - chenkegarfield的博客
這里我們設置勾上application verifiwer,該工具主要可用來對程序做一些穩定性的檢測,本次調試主要用于保存棧的相關信息。同時設置stack backtrace即棧的大小為10.
2)運行windbg,打開第一步編譯的程序,并使其跑起來;此時你查看任務管理器中的句柄信息,會發現相應進程句柄一直在增加。
用windbg的!htrace定位句柄泄露 - chenkegarfield - chenkegarfield的博客
3)windbg用ctrl+break命令中斷進程運行,用!htrace -enable命令開啟句柄檢測;htrace提供了進行句柄相關檢測的命令,可查看windbg幫助。
用windbg的!htrace定位句柄泄露 - chenkegarfield - chenkegarfield的博客
同時用g命令讓程序運行。
用windbg的!htrace定位句柄泄露 - chenkegarfield - chenkegarfield的博客
4)再次中斷進程,使用!htrace -snapshot命令,獲得此時進程句柄的鏡像。并再次讓程序運行。
用windbg的!htrace定位句柄泄露 - chenkegarfield - chenkegarfield的博客
5)第三次中斷進程運行,我們再使用!htrace -diff命令獲得當前句柄狀態與第4步 snapshot鏡像句柄的差異;
用windbg的!htrace定位句柄泄露 - chenkegarfield - chenkegarfield的博客
我們可以發現:新增很多打開的句柄,平常情況下這些打開的句柄有可能不是泄露,需要具體分析,但是本次示例程序太簡單,所以剛好所有打開的句柄都屬于泄露的。
6)我們使用lsa 傳遞指定位置對應的代碼,lsa ? handlew2!fun4+0x0000002e
用windbg的!htrace定位句柄泄露 - chenkegarfield - chenkegarfield的博客
到這里,我們就找到了泄露句柄的函數。
Windbg Debugger’s !htrace extension is very handy to debug handle leak.
The process essentially boils down to the following simple steps:
1. ? ? ? Enable trace
2. ? ? ? Take a snapshot
3. ? ? ? Run scenario
4. ? ? ? Show the diff
On step 4, !htrace will show all the extra opened handles after the last snapshot, along with the callstack if available. This greatly helps to debug what handles are leak, and by whom.
Like any other resource leak detection tool, there will be false positives. You need to understand what is a real leak, and what is just a transient allocation.
?
!htrace
The !htrace extension displays stack trace information for one or more handles.
Syntax
User-Mode Syntax
!htrace [Handle [Max_Traces]]?
!htrace -enable [Max_Traces]
!htrace -snapshot
!htrace -diff
!htrace -disable
!htrace -??
Kernel-Mode Syntax
!htrace [Handle [Process [Max_Traces]]]?
!htrace -??
Parameters
Handle
Specifies the handle whose stack trace will be displayed. If Handle is 0 or omitted, stack traces for all handles in the process will be displayed.
Process
(Kernel mode only) Specifies the process whose handles will be displayed. If Process is 0 or omitted, then the current process is used. In user mode, the current process is always used.
Max_Traces
Specifies the maximum number of stack traces to display. In user mode, if this parameter is omitted, then all the stack traces for the target process will be displayed.
-enable
(User mode only) Enables handle tracing and takes the first snapshot of the handle information to use as the initial state by the -diff option.
-snapshot
(User mode only) Takes a snapshot of the current handle information to use as the initial state by the-diff option.
-diff
(User mode only) Compares current handle information with the last snapshot of handle information that was taken. Displays all handles that are still open.
-disable
(User mode only; Windows Server 2003 and later only) Disables handle tracing. In Windows XP, handle tracing can be disabled only by terminating the target process.
-?
Displays some brief Help text for this extension in the Debugger Command window.
DLL
Windows NT 4.0
Unavailable
Windows 2000
Unavailable
Windows XP and later
Kdexts.dll?
Ntsdexts.dll
Comments
Before !htrace can be used, Application Verifier must be activated for the target process, and theDetect invalid handle usage option must be selected. By activating Application Verifier, stack trace information is saved each time the process opens a handle, closes a handle, or references an invalid handle. It is this stack trace information that !htrace displays. For more information, seeApplication Verifier.
The following example displays information about all handles in process 0x81400300:
kd> !htrace 0 81400300
Process 0x81400300
ObjectTable 0xE10CCF60
--------------------------------------
Handle 0x7CC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7CC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE23B2: KERNEL32!CreateSemaphoreA+0x66
0x010011C5: badhandle!main+0x45
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - BAD REFERENCE:
0x8018F709: ntoskrnl!ExMapHandleToPointerEx+0xEA
0x801E10F2: ntoskrnl!ObReferenceObjectByHandle+0x12C
0x801902BE: ntoskrnl!NtSetEvent+0x6C
0x80154965: ntoskrnl!_KiSystemService+0xC4
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Handle 0x7DC - OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE265C: KERNEL32!CreateEventA+0x66
0x010011A0: badhandle!main+0x20
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
--------------------------------------
Parsed 0x6 stack traces.
Dumped 0x5 stack traces.
========
Use !htrace to debug handle leak
https://blogs.msdn.microsoft.com/junfeng/2008/04/21/use-htrace-to-debug-handle-leak/avatar of junfengJunfeng ZhangApril 21, 20083
Share
0
0
Windbg Debugger’s !htrace extension is very handy to debug handle leak.
The process essentially boils down to the following simple steps:
1. ? ? ? Enable trace
2. ? ? ? Take a snapshot
3. ? ? ? Run scenario
4. ? ? ? Show the diff
On step 4, !htrace will show all the extra opened handles after the last snapshot, along with the callstack if available. This greatly helps to debug what handles are leak, and by whom.
Like any other resource leak detection tool, there will be false positives. You need to understand what is a real leak, and what is just a transient allocation.
!htrace
The !htrace extension displays stack trace information for one or more handles.
Syntax
User-Mode Syntax
!htrace [Handle [Max_Traces]]?
!htrace -enable [Max_Traces]
!htrace -snapshot
!htrace -diff
!htrace -disable
!htrace -??
Kernel-Mode Syntax
!htrace [Handle [Process [Max_Traces]]]?
!htrace -??
Parameters
Handle
Specifies the handle whose stack trace will be displayed. If Handle is 0 or omitted, stack traces for all handles in the process will be displayed.
Process
(Kernel mode only) Specifies the process whose handles will be displayed. If Process is 0 or omitted, then the current process is used. In user mode, the current process is always used.
Max_Traces
Specifies the maximum number of stack traces to display. In user mode, if this parameter is omitted, then all the stack traces for the target process will be displayed.
-enable
(User mode only) Enables handle tracing and takes the first snapshot of the handle information to use as the initial state by the -diff option.
-snapshot
(User mode only) Takes a snapshot of the current handle information to use as the initial state by the -diff option.
-diff
(User mode only) Compares current handle information with the last snapshot of handle information that was taken. Displays all handles that are still open.
-disable
(User mode only; Windows Server 2003 and later only) Disables handle tracing. In Windows XP, handle tracing can be disabled only by terminating the target process.
-?
Displays some brief Help text for this extension in the Debugger Command window.
DLL
Windows NT 4.0
Unavailable
Windows 2000
Unavailable
Windows XP and later
Kdexts.dll?
Ntsdexts.dll
Comments
Before !htrace can be used, Application Verifier must be activated for the target process, and the Detect invalid handle usage option must be selected. By activating Application Verifier, stack trace information is saved each time the process opens a handle, closes a handle, or references an invalid handle. It is this stack trace information that !htrace displays. For more information, see Application Verifier.
The following example displays information about all handles in process 0x81400300:
kd> !htrace 0 81400300
Process 0x81400300
ObjectTable 0xE10CCF60
————————————–
Handle 0x7CC – CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
————————————–
Handle 0x7CC – OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE23B2: KERNEL32!CreateSemaphoreA+0x66
0x010011C5: badhandle!main+0x45
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
————————————–
Handle 0x7DC – BAD REFERENCE:
0x8018F709: ntoskrnl!ExMapHandleToPointerEx+0xEA
0x801E10F2: ntoskrnl!ObReferenceObjectByHandle+0x12C
0x801902BE: ntoskrnl!NtSetEvent+0x6C
0x80154965: ntoskrnl!_KiSystemService+0xC4
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
————————————–
Handle 0x7DC – CLOSE:
0x8018FCB9: ntoskrnl!ExDestroyHandle+0x103
0x801E1D12: ntoskrnl!ObpCloseHandleTableEntry+0xE4
0x801E1DD9: ntoskrnl!ObpCloseHandle+0x85
0x801E1EDD: ntoskrnl!NtClose+0x19
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
————————————–
Handle 0x7DC – OPEN:
0x8018F44A: ntoskrnl!ExCreateHandle+0x94
0x801E3390: ntoskrnl!ObpCreateUnnamedHandle+0x10C
0x801E7317: ntoskrnl!ObInsertObject+0xC3
0x77DE265C: KERNEL32!CreateEventA+0x66
0x010011A0: badhandle!main+0x20
0x010012C1: badhandle!mainCRTStartup+0xE3
0x77DE0B2F: KERNEL32!BaseProcessStart+0x3D
————————————–
Parsed 0x6 stack traces.
Dumped 0x5 stack traces.
Additional Information
For information about handles, see the Microsoft Windows SDK documentation and Microsoft Windows Internals by Mark Russinovich and David Solomon. To display further information about a specific handle, use the !handle extension.
2007 Microsoft Corporation
Send feedback on this topic
Tags Debugging
Comments (3)
Name *?
Email *?
Website?
Post Comment
Microsoft news and tips » Use !htrace to debug handle leak
April 21, 2008 at 12:01 pm
PingBack from http://microsoftnews.askpcdoc.com/?p=3494
Reply
Koby Kahane
April 21, 2008 at 2:30 pm
!htrace is an awesome extension, easily one of my favorites.
I recall debugging a registry handle leak in third-party code and a desktop handle leak in in-house code, among other things, using this great tool.
A great example of the added value of dbgeng extensions given to Windbg over alternative debuggers such Ollydbg, Visual Studio, etc.
I think that in a more general sense, some great capabilities of App Verifier are unknown to the developer community at large and should be evangelized more.
Hopefully options providing finer granularity will be added to the !htrace extension command in future DTW releases, allowing filtering handles based on their type and filtering stack traces based on the contents, !findstack style, and so on.
Reply
Norman Diamond
April 21, 2008 at 8:58 pm
The link to
mk:@MSITStore:C:debuggersdebugger.chm::/hh/Debugger/AppVerif2_437533d6-daa8-4fe9-90da-a7717ebc9683.xml.htm
doesn’t work in Internet Explorer, even though I have the MSDN library installed.
Reply
========
Htrace查找handle泄露點操作步驟
http://blog.csdn.net/tpriwwq/article/details/90827091. 使用Windbg -File-OpenExecutable,打開要調試exe.
? ? ?程序啟動后,系統會暫停程序一次.這個是正常的.
2. 啟用htrace: ?(在windbg的命令窗口中輸入)!htrace -enable
3. 運行程序: (在windbg的命令窗口中輸入)g
4.某個時刻創建一次句柄快照:(在windbg的命令窗口中輸入)!htrace -snapshot
觀察到handle增長,暫停進程(Debug - Break)
繼續運行后進行一次句柄快照對比:(在windbg的命令窗口中輸入)!htrace -diff
5.使用(在windbg的命令窗口中輸入)!htrace ***(此處為handle的地址),即可跟蹤到handle泄露點
6.根據handle的輸出信息,如果有源碼,則可以使用(在windbg的命令窗口中輸入)lsa 傳遞指定位置對應的代碼,定位到handle泄露點
?----------------------
個人體會:
通過Htrace 檢測到的Handle不一定就是泄露的Handle,在跟蹤中常碰到句柄增長了1個,通過
Htrace -diff 獲取一大堆的情形。所以要準確定位到泄漏Handle,還需要結合編碼進行分析。
?
------------------------------------------------------------------------------------
?相對于Htrace, ?使用ProcessExplorer和Handle工具也可以查找handle泄露點.
1.ProcessExplorer
為便于觀察,需對ProcessExplorer進行設置
? ? ?設置 1)view- show unnamed handle。。。; //顯示handle
? ? ? ? ? ? ? ?2 ) view - ShowLowerPane ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ?3)如果想看實時變化情況,調整 ? options - Difference Highlight Duration,調整為9s
? ? ? ? ? ? ? ?4) ?如果想看某一時間段的變化, view - Update Speed 改為 Paused,按 F5獲取列表,運行一段時間后,
再次按F5獲取新的對象列表.
2. Handle
cmd輸入: Handle -s -p (Processname | ProcessID)
========
windbg檢測句柄泄露(定位到具體代碼)
http://blog.csdn.net/yockie/article/details/406035111.構造一個測試用例
[cpp] view plain copy 在CODE上查看代碼片派生到我的代碼片
#include "stdafx.h" ?
#include <Windows.h> ?
??
void NormalFunc() ?
{ ?
? ? HANDLE hEvent; ?
? ? hEvent = CreateEvent(NULL,TRUE,TRUE,NULL); ?
? ? CloseHandle(hEvent); ?
} ?
??
void HandleLeakFunc() ?
{ ?
? ? HANDLE hEvent; ?
? ? hEvent = CreateEvent(NULL,TRUE,TRUE,NULL); ?
? ? //CloseHandle(hEvent); ? ? ?//有句柄泄露 ?
} ?
??
int main() ?
{ ?
? ? while(1) ?
? ? { ?
? ? ? ? NormalFunc(); ?
? ? ? ? HandleLeakFunc(); ?
? ? ? ? Sleep(200); ?
? ? } ?
??
? ? return 0; ?
} ?
2.windbg調試
(1)運行windbg,首先確定符號表地址填寫OK了。
(2)我們選擇"Open Executable"再選擇上述測試用例生成的exe,可能在實際工程中經常是"Attach to a process"。再看任務管理器會發現這個進程的句柄數飆升:
(3)windbg用ctrl+break命令中斷進程運行,用!htrace -enable命令開啟句柄檢測;htrace命令提供了進行句柄檢測相關的命令,可查看windbg幫助,如圖:
(4)再使用!htrace -snapshot命令,獲得此時進程句柄的鏡像。讓程序繼續運行。
(5)中斷進程運行,使用!htrace -diff命令獲得當前句柄狀態與第4步 snapshot鏡像句柄的差異;
(6)輸出很多打開的句柄,需要具體情況具體分析,最好對照代碼來看。這里是測試,所以比較簡單,一眼就看出來了。
(7)使用lsa 傳遞指定位置對應的代碼,lsa Lab2010_2!HandleLeakFunc+0x00000012
總結一下,就是3個命令:
!htrace -enable
!htrace -snapshot
//do something
!htrace -diff
========
列舉所有Handle(句柄)以及查看Handle 信息
http://wingeek.blog.51cto.com/1226974/274066/WinDBG的 !handle 命令可以讓你方便調試句柄(handle)。
查看進程內所有句柄, 輸入命令行
0:014> !handle
Handle 4
? Type ? ? ? ? ?Directory
Handle 8
? Type ? ? ? ? ?Process
Handle c
? Type ? ? ? ? ?Key
Handle 10
? Type ? ? ? ? ?Mutant
Handle 14
? Type ? ? ? ? ?ALPC Port
Handle 18
? Type ? ? ? ? ?Key
Handle 1c
? Type ? ? ? ? ?Event
Handle 20
? Type ? ? ? ? ?Key
?... (省略)
Handle 7e0
? Type ? ? ? ? ?Mutant
392 Handles
Type ? ? ? ? ? ?Count
None ? ? ? ? ? ?17
Event ? ? ? ? ? 134
Section ? ? ? ? 47
File ? ? ? ? ? ?35
Directory ? ? ? 3
Mutant ? ? ? ? ?34
WindowStation ? 2
Semaphore ? ? ? 24
Key ? ? ? ? ? ? 47
Token ? ? ? ? ? 1
Process ? ? ? ? 3
Thread ? ? ? ? ?27
Desktop ? ? ? ? 1
IoCompletion ? ?4
Timer ? ? ? ? ? 5
Job ? ? ? ? ? ? 1
KeyedEvent ? ? ?1
TpWorkerFactory 6
從WinDBG輸出結果我們可以看到所有句柄的類型和值,以及統計信息(一共392個handle,其中有35個文件句柄,47個注冊表句柄 .... )。
如果想查看某個句柄的詳細信息, 可以用命令:
0:014> !handle 0x5c8 f
Handle 5c8
? Type ? ? ? ? ?Key
? Attributes ? ?0
? GrantedAccess 0x20019:
? ? ? ? ?ReadControl
? ? ? ? ?QueryValue,EnumSubKey,Notify
? HandleCount ? 2
? PointerCount ?3
? Name ? ? ? ? ?\REGISTRY\USER\S-1-5-21-2127521184-1604012920-1887927527-2966534\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts
? Object Specific Information
? ? Key last write time: ?16:52:14. 5/20/2009
? ? Key name FileExts
0x5c8 是句柄的值, 參數f 表示顯示全部信息。 我們可以看到句柄0x5c8 是注冊表句柄,路徑為\REGISTRY\USER\S-1-5-21-2127521184-1604012920-1887927527-2966534\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts。
值得一提的是,WinDBG 還提供了!htrace 命令,可以很方便來用檢查句柄泄露(Handle Leak), 下次再寫篇blog 專門介紹 !htrace 。
========
總結
以上是生活随笔為你收集整理的windbg !htrace 学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VC++ 自定义消息学习总结
- 下一篇: C#指针使用学习总结