Windbg 를 이용한 Handle leak 찾기
Windbg 를 사용할 경우 !handle 명령을 사용하여 현재 Process 내의 모든 Handle 정보를 확인할 수 있습니다. 이는 Process explorer 를 사용하는 방법과 동일하지만 Process Explorer 에서는 어떤 Handle 이 생성되어 있는지는 확인할 수 있으나 어떤 함수를 통해서 Handle 이 생성되었는지는 알 수 없습니다. 이때 gflags.exe 에서 Object 관련 값을 설정하면 좀더 많은 정보를 확인할 수 있습니다.
Handle leak 이 의심되는 프로그램을 실행시킨 후 WinDbg 를 실행시켜 Attach 시킵니다. 그리고 “!htrace –enable” 명령을 실행하면 간단하게 Handle 이 생성되는 함수가 무엇인지 call stack 을 저장할 수 있습니다.
0:000> !htrace -enable
Handle tracing enabled.
Handle tracing information snapshot successfully taken.
Handle leak 이 의심되는 동작을 하기 전 “!htrace –snapshot” 명령을 수행하여 현재 Handle 정보의 snapshot을 저장한 후 Handle leak 이 의심되는 동작을 한 후 “!htrace -diff” 명령을 실행하면 snapshot 을 설정한 이후 Open Close 되는 모든 Handle 정보를 확인할 수 있습니다. Handle 이 Process, Thread 정보와 함께 Call stack 이 출력되어 어떠한 함수 경로를 통해 Handle 이 Open 되고 Close 되는지 확인할 수 있습니다.
Event 를 생성해서 대기하는 예제를 실행 시키고 WinDbg 를 Attach 시킨 후 “!htrace –enable” 명령을 사용하여 Handle 에 대한 trace 를 enable 시킨 후 Event 를 생성한 후 “!htrace -diff" 명령을 사용하면 다음과 같이 새로운 Event Handle 이 생성된 것을 확인할 수 있습니다.
0:001> !htrace -diff
Handle tracing information snapshot successfully taken.
0x1a7 new stack traces since the previous snapshot.
Ignoring handles that were already closed...
Outstanding handles opened since the previous snapshot:
--------------------------------------
Handle = 0x00000280 - OPEN
Thread ID = 0x00001e10, Process ID = 0x00000d0c
0x7c81bd9f: kernel32!CreateEventA+0x00000022
0x00412d06: ProcessHangApp!CProcessHangAppDlg::OnBtnHung+0x00000036
0x786a75a2: mfc90d+0x000c75a2
0x786a7cea: mfc90d+0x000c7cea
0x7867da93: mfc90d+0x0009da93
0x786408b4: mfc90d+0x000608b4
0x7863f529: mfc90d+0x0005f529
0x7863f462: mfc90d+0x0005f462
0x7863c8e0: mfc90d+0x0005c8e0
0x7863cea6: mfc90d+0x0005cea6
--------------------------------------
Displayed 0x1 stack traces for outstanding handles opened since the previous snapshot.
Event 를 생성한 함수를 살펴 보도록 하겠습니다.
0:001> lsa ProcessHangApp!CProcessHangAppDlg::OnBtnHung
170: return (HCURSOR) m_hIcon;
171: }
172:
173: void CProcessHangAppDlg::OnBtnHung()
> 174: {
175: // NAMED EVENT »ý¼º(¾ò±â)
176: HANDLE hNmdEvent = CreateEvent(NULL, // security attribute
177: FALSE, // manual reset
178: TRUE, // signaled
179: _T("Win32UserDebug"));
Handle 280
Type Event
Attributes 0
GrantedAccess 0x1f0003:
Delete,ReadControl,WriteDac,WriteOwner,Synch
QueryState,ModifyState
HandleCount 2
PointerCount 4
Name \BaseNamedObjects\Win32UserDebug
Object Specific Information
Event Type Auto Reset
Event is Waiting
Comments
- Anonymous
October 22, 2008
The comment has been removed