[Troubleshooting Tool] Gflags.exe

Gflags.exe Windows System Diagnostics 를 위해 debugging tools for windows에서 제공하는 Tool이다.

상위의 그림만 봐서는 이해하기 어려울 수도 있지만, Application에 대한 System registry의 일부 설정을 통하여 메모리누수나 handle 누수를 tracking 하거나 pageheap enable 하여 Heap corruption Troubleshooting 할 수 있다.

 

메모리누수에 대한 Gflags 설정.


메모리누수를 Check하기 위해서는 gflags.exe UMDH(User Mode Dump Heap)이라는 Tool도 필요하다. UMDH 역시 Debugging tools for Windows에 포함되어 있는 Tool이다.

 

1)     Gflags에 보면, image file tab에서 Create user mode stack trace database라는 option enable 한다. (그전에 image text box에 해당 image 이름을 입력해야 한다) Command 창에서는 gflags –i  CrashApp.exe +ust하고 실행하면 된다.

2)     설정이 되었는지는 레지스트리를 통해서 확인할 있는 ,  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\CrashApp.exe 이동하여, key중에 REG_DWORD GlobalFlag 존재하는 확인하고, 해당 값이 0x1000으로 설정되어 있으면 정상적으로 설정이 것이다.

3)     그리고, UDDH를 위해서 Symbol 설정을 해야 한다. Command창에서 SET _NT_SYMBOL_PATH=C:\LeakAppSymbols;SRV*c:\symbols*http://msdl.microsoft.com/download/symbols” 하여 환경변수로 설정하고,

4)     Application을 수행한 후, Leak 현상이 발생하기 전 해당 Command 창에

“umdh –p:PID > C:\start.txt” 를 수행한다.

5)     충분히 Leak 현상이 발생하고 나면, “umdh –p:PID > end.txt” command창에서 한번 더 수행을 하고,

6)     마지막으로 해당 command 창에서 umdh –d start.txt end.txt > result.txt” 를 수행하여 결과를 얻는 다.

 

결과 report Leak이전에 잡은 Log와 이후에 잡은 Log를 통해서 차이가 발생하는 Allocation에 대한 결과를 다음과 같이 보여준다. Symbol이 맞아야 Callstack에서 Allocation이 발생하는 Code의 위치를 정확히 확인할 수 있다.

///////////////

+   20480 (  20480 -      0)      1 allocs  BackTrace1516DC

+       1 (      1 -      0)         BackTrace1516DC allocations

 

           ntdll!RtlTimeToElapsedTimeFields+00001963

           buggy!memoryLeak+00000036 (d:\myprog\dbgt\exe\buggy\buggy.cpp, 20)

           buggy!wmain+000000C1 (d:\myprog\dbgt\exe\buggy\buggy.cpp, 225)

           buggy!wmainCRTStartup+0000016A

           kernel32!BaseThreadInitThunk+00000012

           ntdll!RtlInitializeExceptionChain+00000063

           ntdll!RtlInitializeExceptionChain+00000036

 

 

Total increase ==  20480 requested +     24 overhead =  20504

/////////////

여기서 increase 20480 bytes 단위이다.

 

             Heap Corruption에 대한 gflags의 설정

Heap Code에서 사용하는 Memory Block으로 Application에서 메모리 할당이나 해제 시 잘못된 사용으로 인하여 Corruption이 발생할 수 있다. 일반적인 Heap corruption이 발생하는 경우는 다음과 같다.

²  Buffer overrun

²  Buffer underrun

²  Double Free

²  Free block에 대한 access

²  메모리 재사용에 대한 문제, (예를 들어, 메모리를 free하고 동일한 size를 재사용할 때, 동일한 address가 잡힐 것이라는 기대감에서 발생할 수 있는 문제. 등등

 

Heap Corruption 은 임의의 Heap block이 깨진 이후 다른 시점에 Allocation이나 Memory 사용시 예기치 않게 Access Violation이 발생할 수 있기 때문에 AV 순간 Crash dump를 수집한다고 해도 해당 Callstack이 문제 근원이 되는 Callstack이 아닐 가능성이 매우 크다. 이를 위해서 Gflags allocation Check하도록 설정하여 잘못된 사용시 이를 Debugger를 통해 알려줄 수 있도록 도와준다.

 

-       Normal Pageheap

²  free될 때만 allocation check

²  gflags –p /enable CrashApp.exe

²  High Memory usageprocess를 위해서는 “gflags.exe –p /enable lsass.exe /decommit /random 20” 를 이용할 수 있다. random 2020% pageheapenable 된다는 의미.

 

-       Full Pageheap

²   No access pages를 사용하여 Allocation block padding

²  gflags –p /enable CrashApp.exe /full

²  만일, /decommit option을 이용하면, Memory1/2 로 줄일 수 있다.

n  gflags –p /enable CrashApp.exe /full /decommit

n  decommit No access pages 대신에 reserved virtual memory zone을 이용함.

 

Heap이 깨졌다는 것은 어떻게 알까? 먼저, AV crash dump를 확인하고, Heap corruption 여부를 확인하여 다시 Crash dump를 수집하게 된다. 간혹, 다음과 같은 Function stack에서 AV가 발생하는 것을 볼 수 있다.


ntdll!RtlpCoalesceFreeBlocks+0x10c
ntdll!RtlFreeHeap+0x142
. . .


또는


ntdll!RtlpCoalesceFreeBlocks+0x10c
ntdll!RtlpExtendHeap+0x1c1
ntdll!RtlAllocateHeap+0x3b6
. . .


그리고, 문제가 발생한 AddressheapCheck해봤을 때 (“!heap –x <address>” command를 수행) Heap block size가 이상하거나 bad pointer(garbage allocation data 또는 알 수 없는 영역)로 의심이 간다면, Heap corruption을 조심스레 의심해 볼 수 있다.

 

Pageheap에 따른 Heap block의 구조는 아래의 문서를 참조한다. 중요한 것은 Block headersuffix bytes 인데, 이는 Heap blockAllocated된 것인지 Free된 것인지를 확인할 수 있는 정보가 된다.

//// http://msdn.microsoft.com/en-us/library/cc266933.aspx발췌...

The following diagrams show the arrangement of heap blocks. These are valid in Windows 2000 (Service Pack 1 and later), Windows XP, and later versions of Windows.

Light page heap block — allocated:

 +-----+---------------+---+                                  
 |     |               |   |                                  
 +-----+---------------+---+                                  
    ^         ^          ^                                    
    |         |          8 suffix bytes (filled with 0xA0)    
    |         User allocation (filled with E0 if zeroing not requested) 
    Block header (starts with 0xABCDAAAA and ends with 0xDCBAAAAA) 

Light page heap block freed:

 +-----+---------------+---+                                  
 |     |               |   |                                  
 +-----+---------------+---+                                  
    ^         ^          ^                                    
    |         |          8 suffix bytes (filled with 0xA0)    
    |         User allocation (filled with F0 bytes)          
    Block header (starts with 0xABCDAAA9 and ends with 0xDCBAAA9) 

Full page heap block — allocated:

 +-----+---------+---+-------                                 
 |     |         |   |  ... N/A page                          
 +-----+---------+---+-------                                 
    ^       ^      ^                                          
    |       |      0-7 suffix bytes (filled with 0xD0)        
    |       User allocation (if zeroing not requested, filled   
            with E0 in Windows 2000 and C0 in Windows XP)       
    Block header (starts with 0xABCDBBBB and ends with 0xDCBABBBB) 

Full page heap block — freed:

 +-----+---------+---+-------                                 
 |     |         |   |  ... N/A page                          
 +-----+---------+---+-------                                 
    ^       ^      ^                                          
    |       |      0-7 suffix bytes (filled with 0xD0)        
    |       User allocation (filled with F0 bytes)            
    Block header (starts with 0xABCDBBA and ends with 0xDCBABBBA) 

/////

추가적으로 Handle leak의 경우도 gflags 를 이용하여 Troubleshooting 할 수 있다. 참조:http://byung.egloos.com/4481638

by 강세윤 | 2008/11/26 18:01 | Windows debugging | 트랙백 | 덧글(0)
트랙백 주소 : http://byung.egloos.com/tb/4752325
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

< 이전페이지 다음페이지 >