Handle Leaks은 감지하기가 어렵지 않은 반면, (Task Manager에서 “핸들 수”를 Check하면 증가하고 있음을 알 수 있다.) T-shooting은 쉽지 않은 issue 중에 하나이다. 이를 T-shooting할 수 있는 대표적인 방법이 WinDBG의 htrace extension을 이용하는 것인데, 실시간으로 Monitoring 하여 잡아 낸다는 점에서 Repro가 용이해야 하고, Debugger에 의해 Monitoring 하는 동안 작업에 Risk가 있다는 점, 그리고 얻어진 분석 데이터에 대한 남다른 직관(?)이 필요하다는 점에서 조금은 껄끄럽다. 그럼에도 불구하고 T-shooting을 해야 한다면, 다음과 같이 할 수 있다.
Handle leaks가 의심되는 Application이 있다면, gflags에서 다음을 Check 한다.

그리고 나서, Debugger(windbg.exe)를 통해서 해당 Application을 수행하고, htrace extension을 이용해서 leak trace를 enable 한다.
0:001> !htrace -enable
Handle tracing enabled.
Handle tracing information snapshot successfully taken.
그리고, 일단, 한번 snapshot을 하나 떠 놓고, g 해서 handle leak을 어느 정도 문제가 되는 선까지 유발한다.
0:001> !htrace -snapshot
Handle tracing information snapshot successfully taken.
0:001> g
Leak이 두드러지면, break을 한 후에 snapshot 시점과의 차이를 살펴볼 수 있다.
(109c.111c): Break instruction exception - code 80000003 (first chance)
eax=7ffd3000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c93120e esp=003bffcc ebp=003bfff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint:
7c93120e cc int 3
0:001> !htrace -diff
Handle tracing information snapshot successfully taken.
0xcf new stack traces since the previous snapshot.
Ignoring handles that were already closed...
Outstanding handles opened since the previous snapshot:
--------------------------------------
Handle = 0x00000500 - OPEN
Thread ID = 0x000003bc, Process ID = 0x0000109c
. . .
--------------------------------------
Handle = 0x00000718 - OPEN
Thread ID = 0x000003bc, Process ID = 0x0000109c
0x7c8308bf: kernel32!CreateEventA+0x00000068
0x0041256e: leakApplication!fun4+0x0000002e
0x00412493: leakApplication!fun2+0x00000023
0x004123f1: leakApplication!main+0x00000031
0x004129bc: leakApplication!__tmainCRTStartup+0x0000015f
0x7c817067: kernel32!BaseProcessStart+0x00000023
--------------------------------------
Handle = 0x00000720 - OPEN
Thread ID = 0x000003bc, Process ID = 0x0000109c
0x7c8308bf: kernel32!CreateEventA+0x00000068
0x0041256e: leakApplication!fun4+0x0000002e
0x00412493: leakApplication!fun2+0x00000023
0x004123f1: leakApplication!main+0x00000031
0x004129bc: leakApplication!__tmainCRTStartup+0x0000015f
0x7c817067: kernel32!BaseProcessStart+0x00000023
--------------------------------------
Displayed 0x45 stack traces for outstanding handles opened since the previous snapshot.
상위의 stack trace는 Leak일 수도 아니면, 정상적인 handle open일 수도 있으므로, Application수준에서 검증해야 할 필요가 있다.
// 아래는 source path가 linking 되어야만 확인할 수 있다.
0:001> lsa leakApplication!fun4+0x0000002e
41: void fun4(void)
42: {
43: HANDLE hEvent2;
44:
> 45: hEvent2 = CreateEvent(NULL,TRUE,TRUE,NULL);
46: }



덧글