태그 : debugging
2009/04/06   Stack Corruption 2
2009/03/11   Mini Dump에서 managed callstack 복원
2009/03/02   골치 아픈 Memory Fragmentation
2009/02/25   Stack Overflow에 대한 Debugging
2009/02/17   Kernel Mode에서의 High CPU issue
Stack Corruption 2

다음과 같은 Crash는 빈번하게 볼 수 있다. Stack이 깨져있는 모습.

 

0:003> kbL

ChildEBP RetAddr  Args to Child             

WARNING: Frame IP not in any known module. Following frames may be wrong.

0470fc54 1a43fa39 058dfe44 00000000 001db2c0 0x251fcf

0470fc70 1a41dfdb 00000001 0470fc94 1a406bd4 ttt!CBaseMy::Neutralize+0x35

 

0:003> r

eax=050d2000 ebx=00000000 ecx=00251f18 edx=00000000 esi=001db2c0 edi=00000000

eip=00251fcf esp=0470fc58 ebp=0470fc70 iopl=0         nv up ei pl nz na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206

00251fcf 006022          add     byte ptr [eax+22h],ah      ds:0023:050d2022=??

 

보면, 0x251fcf Function Name은 아닐 것이다. Garbage 임에 틀림없다. 그리고 Register 를 보면, eax 는 잘못되었음을 보여주고 있다. 이러한 Callstack에서 문제가 발생한 원인을 찾기 위해서는 마지막에 정상적으로 수행된 Function에서 부터 Check 할 필요가 있다. Windbg에서 kb 명령어를 수행할 줄 알아도 그 의미를 알지 못하면 아무 소용이 없다. . 그럼 어디를 어떻게 봐야 할 까. 다시 한번 Callstack을 보자.

 

0:003> kbL

ChildEBP RetAddr  Args to Child             

WARNING: Frame IP not in any known module. Following frames may be wrong.

0470fc54 1a43fa39 058dfe44 00000000 001db2c0 0x251fcf

0470fc70 1a41dfdb 00000001 0470fc94 1a406bd4 ttt!CBaseMy::Neutralize+0x35

 

Callstack에서 보여주고 있는 것은 Neutralize Function 안에서 뭔가 임의의 Function Call되었고 그것의 Function Name은 알 수 없다는 것이다. 만일 적절한 Function Name Debugger가 알 수 있었다면, 0x251fcf 라는 값을 출력하진 않았을 것이다. 하지만, 또 한가지 알 수 있는 것은 뭔지 모르는 마지막 Function Call에 대한 return address 0x1a43fa39 라는 것이다. 이것이 깨졌는지 Check 해 봐야 한다. 만일, 이것 역시 깨졌다면, 다시 raw stack을 점검해야 할 것이다. 그러므로, 일단, Neutralize Function Assembly code를 확인할 수 있다.

 

0:003> uf ttt!CBaseMy::Neutralize

  664 1a41df5a 8bff            mov     edi,edi

  664 1a41df5c 56              push    esi

  664 1a41df5d 8bf1            mov     esi,ecx

. . .<중략>

  675 1a41df7d 8b460c          mov     eax,dword ptr [esi+0Ch]

  675 1a41df80 3bc7            cmp     eax,edi

  675 1a41df82 0f85ab1a0200    jne     ttt!CBaseMy::Neutralize +0x2f (1a43fa33)

  677 1a43fa33 8b08            mov     ecx,dword ptr [eax]

  677 1a43fa35 50              push    eax

  677 1a43fa36 ff5108          call    dword ptr [ecx+8]

  678 1a43fa39 897e0c          mov     dword ptr [esi+0Ch],edi

 

결국, 1a43fa39 Assembly code에서 Class member function call 'call dword ptr[ecx+8]' 에 대한 Return Address이다. 다시 assembly code register 값을 살펴보자.

 

0:003> dd @ecx

00251f18  ???????? ???????? ???????? ????????

00251f28  ???????? ???????? ???????? ????????

00251f38  ???????? ???????? ???????? ????????

00251f48  ???????? ???????? 0000ffff 00252c04

 

확실히 ecx 값은 잘못되었다. assembly code를 따라가보면, ecx값은 esi register의 임의의 Offset으로 부터 얻은 값이고, Function의 초입부에 ecx 를 통해서 esi 값을 전달 받는 것으로 봐서는 esithis pointer가 틀림없다. 그러므로, this pointer member class 또는 member 변수에 대한 member function을 호출하는 것에 문제가 있었기 때문에 stack이 깨진 것으로 추측할 수 있으며, member 변수(ecx register) garbage 값이 들어 온 이유에 대해서 Code review를 통해 verify 해야 할 것이다.

by 강세윤 | 2009/04/06 13:27 | Windows debugging | 트랙백 | 덧글(0)
Mini Dump에서 managed callstack 복원

CLR Exception은 일반적으로 1st Chance Exception이므로, 메모리 덤프를 수집 시에 CLR Exception에 대한 Checking이나 1st chance full user dump 로 설정하지 않으며, 일반적인 Operation에 따라서 mini dump로 수집된다. 이 경우에는 메모리 덤프로 부터 충분한 managed 정보를 얻기가 어렵다. 하지만, 몇 가지 tip을 통해 정보를 수집하는 것이 가능할 수 있다. 다음의 예를 보자.

 

다음은 mini dump상에서 !clrstack 을 입력한 결과이다. 보시다시피 정확한 method 정보를 출력해 주진 않는다.

 

Child-SP         RetAddr          Call Site

000000000012c910 00000642803bb906 xxx.Common.dll!Unknown

000000000012c990 00000642803bb6dd xxx.Common.dll!Unknown

000000000012ca90 00000642803b0fb5 xxxex.exe!Unknown

000000000012cae0 000006428046070b xxxex.exe!Unknown

000000000012cbe0 00000642803bfeab xxxex.exe!Unknown

000000000012cc50 00000642803bfd9f xxxex.exe!Unknown

000000000012ccb0 000006427f67d4a2 xxxex.exe!Unknown

 

이를 Native Callstack에서 보면, 아래와 같다. 아래 노란색 블락은 상위의 Managed Callstack matching이 되는 정보이다.

 

Child-SP          RetAddr           Call Site

00000000`0012c6b0 00000000`77d6e314 ntdll!KiRaiseUserExceptionDispatcher+0x3a

00000000`0012c780 00000642`7f67cbd7 kernel32!CloseHandle+0x5f

00000000`0012c7b0 00000642`803bbfee mscorwks!DoNDirectCall__PatchGetThreadCall+0x7b

00000000`0012c850 00000642`803bbccd ttt.IL_STUB(IntPtr)+0x3e

00000000`0012c910 00000642`803bb906 0x642`803bbccd

00000000`0012c990 00000642`803bb6dd 0x642`803bb906

00000000`0012ca90 00000642`803b0fb5 0x642`803bb6dd

00000000`0012cae0 00000642`8046070b 0x642`803b0fb5

00000000`0012cbe0 00000642`803bfeab 0x642`8046070b

00000000`0012cc50 00000642`803bfd9f 0x642`803bfeab

00000000`0012ccb0 00000642`7f67d4a2 0x642`803bfd9f

 

여기서 좀 더 확인할 수 있는 것은 MethodDesc 정보이다. 예를 들어, 0x642`803bbccd MethodDesc Jitted Address이므로, 다음과 같은 몇몇 정보를 더 얻을 수 있다.

 

0:000> !ip2md 0x642`803bbccd

MethodDesc: 000006428016d1e8

Method Name: xxx.Common.dll!Unknown

Class: 00000642801b4f28

MethodTable: 000006428016d340

mdToken: 06000080

Module: 0000064280014320

IsJitted: yes

m_CodeOrIL: 00000642803bbbe0

 

일단, 해당 Method의 정보는 Clrstack의 출력과 동일하게 잘 이해할 수 없는 정보이다. 정확한 Method 명을 알기 위해서 해당 assembly에 대한 Binary가 필요하다. Binary에 포함되어 있는 MetaData에 해당 Token 정보를 통해 Method를 확인하는 작업이 가능하다. 이는 ildasm.exe 라는 tool이 정보를 제공할 수 있다. 해당 Binary Ildasm에서 Open 하고, View Menu Meta Info show Click 하면, MetaData 정보를 얻을 수 있다. Find 를 통해서 해당 Token(06000080) 으로 확인해 보면 아래와 같이 해당 Method 이름이 Foo2Bar 임을 알 수 있다.

 

        Method #22 (06000080)

        -------------------------------------------------------

               MethodName: Foo2Bar (06000080)

               Flags     : [Private] [HideBySig] [ReuseSlot]  (00000081)

               RVA       : 0x00004e90

               ImplFlags : [IL] [Managed]  (00000000)

               CallCnvntn: [DEFAULT]

               hasThis

               ReturnType: Void

               1 Arguments

                       Argument #1:  String

               1 Parameters

                       (1) ParamToken : (080000a8) Name : label flags: [none] (00000000)

 

이와 같은 방법을 통해서 mini dump에서 managed callstack을 복원할 수 있다.

by 강세윤 | 2009/03/11 15:50 | Windows debugging | 트랙백 | 덧글(0)
골치 아픈 Memory Fragmentation

Application Debugging을 하다 보면, 간간히 들어오는 Issue OOM(Out Of Memory)에 대한 이슈인데, 이거 생각보다 골치가 아프다. 사실 이를 위해서 DebugDiag UMDH 라는 훌륭한 Tool에 의지하며, Allocation patternCheck 하는 것은 debugging도 아니지만, 눈에 띄는 Allocation pattern이나 메모리상에 보유하는 있는 실제 Allocation(Committed) region이 그다지 높지 않은 데도 불구하고 OOM현상이 발생할 수 있다는 데에 어이없어 질 때가 있다. 그러면서 Application 개발자는 분명히 Allocation/release 를 엄격하게 지켰을 뿐인데... 라고 말하기도 한다. 이런 경우 무엇을 할 수 있을 까.

이는 Memory Fragmentation 현상으로 판단한다. 상당히 자잘한 Memory Alloc이 셀 수 없이 반복되면서 메모리 조각화가 발생하는 것이다. 간혹, 큰 메모리 덩어리가 할당/해제 되기도 하고 그러면서 메모리 조각화는 더 할당 받을 수 있는 free 영역이 있음에도 불구하고 !address Check해보면, 연속된 여분의 메모리 블럭이 존재하지 않아서 OOM을 유발하게끔 한다. 이러한 경우에 일차적으로 할 수 있는 것은 1) 어찌됐든 불필요한 작고 많은 memory 조각들이 Leak으로 존재하는 부분을 제거해야만 한다. 이는 DebugDiag Leak tracking을 통해서 Checking될 수 있다. DebugDiag에서 제공하는 Leak 분석에서 제공하는 Callstack 정보는 그 메모리 보유 Size가 크지 않더라도 Allocation Count Check하여 메모리상에 산재됨으로 인한 Fragmentation의 원인이 되진 않는 지 Check 해볼 수 있다.

2) 두 번째는 문서 http://support.microsoft.com/kb/315407 에서 제공하는 registry key, HeapDecommitFreeBlockThreshold 가 도움이 될 수 있다. 이는 레지스트리에 설정된 값 이상이 되는 경우가 아니면, 재사용을 위해 decommitted 되지 않는 상태로 유지하는 것이다.

 

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager

HeapDecommitFreeBlockThreshold REG_DWORD - 0x00040000 (권고)

 

3)사실 2번째 방법이 Application을 위해서 얼마나 효율적인지 경험해보진 못했다. 아마도 Windows XP/2003에서 도입된 LFH (Low Fragmentation Heap)을 사용하도록 Application을 구성하는 것이 가장 효율적일지 모르겠다. 이는 문서 http://msdn.microsoft.com/en-us/library/aa366750.aspx 에도 언급되었지만, HeapSetInformation API를 이용해서 HeapCompatibilityInformation(0) 값을 parameter 전달함으로써 Application Level에서 설정할 수 있다. http://msdn.microsoft.com/en-us/library/aa366705(VS.85).aspx 문서에는 다음과 같은 예제를 확인할 수 있다. 이는 Application에서 사용하는 모든 HeapLFH를 사용하도록 설정할 수 있다.

 

HANDLE heaps[1025];

  DWORD nheaps = GetProcessHeaps(1024, heaps);

 

  for (DWORD i = 0; i < nheaps; i++) {

    ULONG  HeapFragValue = 2;

    HeapSetInformation(heaps[i],

                       HeapCompatibilityInformation,

                       &HeapFragValue,

                       sizeof(HeapFragValue));

  }

이러한 것들이 Memory Fragmentation을 위해 도움이 될 듯 하다.

by 강세윤 | 2009/03/02 18:06 | Windows debugging | 트랙백 | 덧글(0)
Stack Overflow에 대한 Debugging

Program의 수행에서 CPU의 연산을 위해 Stack을 사용한다는 점에서 Stack Size가 제한되어 있다는 것은 개발자라면 항상 염두에 두고 있을 것이다. 그러므로, 무한 재귀 호출되는 Function이나 과도하게 Stack 상에다 Allocation한 후(일반적으로 Local variables parameters Stack에 저장된다.) Exception이나 비정상적인 operation으로 인하여 Stackunwind 되지 않는 다면, 예기치 않은 Stack overflow를 맞을 수 있다. 다음의 Stack overflow dump case를 예로 든다.

 

일단, 메모리덤프를 Open 하면, 대번 Stack Overflow임을 알 수 있다.

 

(24f8.f64): Stack overflow - code c00000fd (first/second chance not available)

eax=000900a0 ebx=00000000 ecx=08ac2bf0 edx=0e010026 esi=0e010024 edi=08aff134

eip=033f9577 esp=08afebe8 ebp=08afec1c iopl=0         nv up ei pl nz na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010206

*** WARNING: Unable to verify checksum for ttt.dll

*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ttt.dll -

ttt!DllUnregisterServer+0x33a4:

033f9577 8501            test    dword ptr [ecx],eax  ds:0023:08ac2bf0=00000000

 

Stack Size는 다음과 같이 Check 할 수 있다.

 

0:066> !teb

TEB at 7fefd000

    ExceptionList:        08afec10

    StackBase:            08b00000

    StackLimit:           08ac1000

    SubSystemTib:         00000000

    FiberData:            00001e00

    ArbitraryUserPointer: 00000000

    Self:                 7fefd000

    EnvironmentPointer:   00000000

    ClientId:             000024f8 . 00000f64

    RpcHandle:            00000000

    Tls Storage:          7fefd02c

    PEB Address:          7ffd8000

    LastErrorValue:       0

    LastStatusValue:      c0150008

    Count Owned Locks:    0

    HardErrorMode:        0

 

0:066> ? 08b00000 - 08ac1000

Evaluate expression: 258048 = 0003f000

 

실제, Max Allocation할 수 있는 Stack Size를 확인해 보면, 대략 256k임을 확인할 수 있다. 이는 아래와 같은 TEB Structure DeallocationStack 값을 확인하면 되며, 이는 http://msdn.microsoft.com/en-us/library/cc267849.aspx 문서를 참조하거나 debugging tools for windows help에서 참조할 수 있다.

 

typedef struct _TEB {
    NT_TIB NtTib;
    PVOID  EnvironmentPointer;
    CLIENT_ID ClientId;
    PVOID ActiveRpcHandle;
    PVOID ThreadLocalStoragePointer;
    PPEB ProcessEnvironmentBlock;
    ULONG LastErrorValue;
    .....
    PVOID DeallocationStack;
    .....
} TEB;

0:066> dd 7fefd000+e0c L1

7fefde0c  08ac0000

 

0:066> ? 08b00000 - 08ac0000

Evaluate expression: 262144 = 00040000  <---- 256k Max allocation size

 

그러므로, 현재 사용하는 Stack3f000 으로 Max Stack Size, 40000 에 도달하고 있음을 확인할 수 있다.

 

원인을 찾기 위해선 무엇보다도 먼저 재귀 호출이 있는 지 확인이 필요한데, 이는 Callstack을 확인하는 작업이 필요할 듯 하다. 일단, 해당 case에서는 안타깝게도 해당 모듈에 대한 Symbol이 정확하지 않아서 확인이 불가능했으며, 정확한 symbol이 존재한다면 아래의 Callstack에서 확인된 Function Check해야 한다.

 

0:066> kbL

ChildEBP RetAddr  Args to Child             

WARNING: Stack unwind information not available. Following frames may be wrong.

08afec1c 033f4de9 0df4002c 08aff0fc 0000fde9 ttt!DllUnregisterServer+0x33a4 <-- Symbol 맞지 않아서 이렇게 보이는 것임.

08aff118 033f40c8 0b056198 0b056228 00000000 ttt+0x4de9

08aff170 762e31eb 0b055f20 08aff124 08aff120 ttt+0x40c8

08aff198 7635184f 033f3e71 08aff3a0 00000005 rpcrt4!Invoke+0x2a

08aff5c4 7634fc79 09dae6f8 06afcbc8 018be228 rpcrt4!NdrStubCall2+0x27b

08aff614 760527f7 09dae6f8 018be228 06afcbc8 rpcrt4!CStdStubBuffer_Invoke+0xffffdd13

08aff638 76909759 09dae6f8 018be228 06afcbc8 oleaut32!CUnivStubWrapper::Invoke+0xc7

. . .

 

만일, Function의 무한 재귀호출에 의해서 Stack Overflow가 발생한 것이 아니라면, Stack allocation 패턴도 Check해야 한다.

 

0:066> dds esp

08afebe8  75f751ea kernel32!lstrlenW+0x56

08afebec  033f18c5 ttt+0x18c5

08afebf0  08aff134

08afebf4  0b0584a8

08afebf8  08aff148

08afebfc  01e62f00

08afec00  0b0584a8

08afec04  000cc09e

08afec08  08afec24

08afec0c  033f188b ttt+0x188b

08afec10  08aff10c

08afec14  0340c9f0 ttt!DllUnregisterServer+0x1681d

08afec18  00000000

08afec1c  08aff118

08afec20  033f4de9 ttt+0x4de9

08afec24  0df4002c

08afec28  08aff0fc

08afec2c  0000fde9

08afec30  0000007b

08afec34  0b055f20

08afec38  00000005

08afec3c  00000000

 

Callstack에서 문제가 발생한 시점이전의 최종 Return Address 33f4de9 인데, 그 이후에 Stack address(상위 raw stack에서의 회색 블럭)local variables 또는 parameters 등으로 사용되므로, 이들 중 Allocation 패턴이 overflow를 의심하게 하는 것이 있는 지 Check가 필요하다.

 

0:066> dc 0b0584a8

0b0584a8  0340e448 0b0500c4 00000000 00000000  H.@.............

0b0584b8  ee7ff470 08002142 00000001 0000261c  p...B!.......&..

0b0584c8  0000261c 000a000d 006f0043 0074006e  .&......C.o.n.t.

0b0584d8  006e0065 002d0074 00790054 00650070  e.n.t.-.T.y.p.e.

0b0584e8  0020003a 006d0069 00670061 002f0065  :. .i.m.a.g.e./.

0b0584f8  00690067 003b0066 006e0020 006d0061  g.i.f.;. .n.a.m.

0b058508  003d0065 00630022 0069006c 005f0070  e.=.".c.l.i.p._.

0b058518  006d0069 00670061 00300065 00330030  i.m.a.g.e.0.0.3.

 

0:066> du 0b0584c8+8

0b0584d0  "Content-Type: image/gif; name="c"

0b058510  "lip_image003.gif"..Content-ID: <"

0b058550  "20090223.44575.001@tagfree.com>."

0b058590  ".Content-Transfer-Encoding: base"

0b0585d0  "64..Content-Location: file:///C:"

0b058610  "/DOCUME~1/jkim/LOCALS~1/Temp/mso"

0b058650  "html1/01/clip_image003.gif....R0"

0b058690  "lGODlhKwHTAHcAMSH+GlNvZnR3YXJlOi"

0b0586d0  "BNaWNyb3NvZnQgT2ZmaWNlACH5BAEAAA"

0b058710  "AALBUACQAA..AcMAhgAAAAAAABoaTSYm"

0b058750  "czMzmWaAgIAzAICAAJaWlpm/v5/P/57O"

0b058790  "/53O/5zN/5vN/5rM/5nM/79N..AL/d/7"

0b0587d0  "7d/7zc/7vb/7ra/7na/73c/7jZ/7fZ/7"

0b058810  "bY/7XY/7TY/7PX/7LX/7DW/6/W/7TX/6"

0b058850  "/V/67V../63U/6vT/6rT/6nT/6jT/6zU"

0b058890  "/6vU/6fS/6bS/6bR/6XR/6TQ/6PQ/6LQ"

0b0588d0  "/6HP/6DP/8Tf/8Le/8He../8De/8Pf/8"

0b058910  "z//9/u/97t/93s/9zr/9vr/9rq/9nq/9"

0b058950  "jq/9rr/9bp/9Xo/9Tn/9fp/9Lm/9Hm/8"

0b058990  "/l../9Pn/87l/83k/9Dm/8zj/8vj/8ni"

0b0589d0  "/8ji/8fh/8bh/8Xg//9mAP//AP//zP7/"

0b058a10  "//7+//3+//z9//v9..//v8//r8//n8//"

0b058a50  "j7//f7//b6//X5//T4//P4//L4//H3//"

. . .<중략>

 

그러므로, 만일, 상위에서 보여주는 몇몇의 data가 과도한 Allocation이나 Allocation 패턴에 의해서 문제 상황을 가져오지는 않는 지는 최종적으로 Source Code를 통해서 확인해봐야 하며, 그러기 위해서는 정확한 Symbol match가 중요함을 잊지 말아야 한다.

by 강세윤 | 2009/02/25 13:56 | Windows debugging | 트랙백(1) | 덧글(0)
Kernel Mode에서의 High CPU issue

High CPU 문제는 Memory Leak 문제와 함께 troubleshooting 하기가 껄끄러운 문제이다. 대부분이 적절한 Tool의 도움을 받아야만 풀 수 있다는 것도 유사하다. 일반적으로 High CPU Issue Performance Monitor의 도움을 받아 특정 Application CPU를 소비하고 있다는 것을 확인할 수 있으며, High CPU 기간 동안 메모리 덤프를 수집하여 누가 지속적으로 CPU time을 잡아 먹고 있는 지를 확인하는 작업이 일반적이었다. 이러한 작업은 kernel mode에서 CPU를 소비하는 경우에 어려움이 있었다. 문제 시점에 kernel dump를 수집한다고 해도 이는 snapshot 이기 때문에 High CPU가 지속되는 과정을 단정 짓기 어려웠다. 그러므로, Kernel trace를 위한 CPU Sampler 와 같은 Tool이 필요한데, Xperf 라는 Tool은 이러한 CPU Sampler를 제공하는 유용한 Tool이다. Perfmon 이나 필요에 의한 Kernel Dump User Dump와 함께 Check 할 경우에 문제를 보다 정확하게 좁힐 수 있다. 특히, High CPU rates Callstack을 제공하는 데, 이는 XP Windows 2003과 같은 Vista 이전 OS에서는 제공되지 않아서 안타깝다.

 

Xperf 는 다음의 Link에서 download 받을 수 있다.

http://msdn.microsoft.com/en-us/performance/cc752957.aspx

 

Download 받으면, trace capture 하는 xperf.exe View할 수 있는 xperfview.exe를 제공한다. 먼저, trace를 수집하는 방법은 여러 가지가 존재하지만, 다음과 같이 간단하게 수집할 수 있다. Vista에서 Administrator 권한 하에서 작업을 한다.

 

          xperf –on DiagEasy

 

그리고, trace 수집이 요구되는 일정기간이 지난 후에 다음과 같이 trace를 종료하여 자료를 수집한다.

 

          xperf –d ktlog.etl

 

이와 같이 High CPU 상태에서의 Kernel trace log를 수집할 수 있다. 그리고, 해당 etl file xperfview.exe에서 open하여 확인한다.

아래의 데이터는 CPU sampling by process의 화면이다.

메뉴에 Graphs 항목이 존재하는 데, CPU Sampling 외에도 CPU Disk utilization by process 또는 thread, interrupt service routine 이나 deferred procedure call, hard faults 그리고, Disk IO detail한 정보들을 graph로 확인할 수 있다. 특히, CPU sampling CPU consuming rates에 따른 Callstack 정보를 확인할 수 있는 데, 해당 정보를 얻기 위해서는 Symbol Files을 맞춰 줄 필요가 있다. Trace 메뉴에 configure symbol paths Click 하면, _NT_SYMBOL_PATH 입력 창이 있는 데, 여기에 Microsoft public symbol path(srv*c:\pubsymbols*http://msdl.microsoft.com/download/symbols )를 입력한다. 그리고, trace 메뉴의 load symbols Check 하면, CPU sampling 시에 Symbols load 될 것이다. 그리고, 마우스를 이용하여 상위 그림에서처럼 임의의 view select 할 수 있고 또는 전체 view select 한 후에 simple summary table click 하면 CPU sampling 정보를 얻을 수 있다.

반드시 load symbols check되어 있는 것을 확인해야 한다. 그래야만 아래 sample data처럼, module에 대한 function 정보를 추출할 수 있다.

CPU sampling data를 보면, 직관적으로 %Weight정보를 통해서 Process CPU rates을 확인할 수 있으며, Module 정보에 따른 어떤 Function CPU를 많이 소비하고 있는 지 여부를 확인할 수 있으므로, 해당 정보를 통해 High CPU Issue를 보다 쉽게 접근할 수 있다. 보다 구체적인 Callstack 정보는 summary table을 Click 하면 다음과 같이 stack 정보를 알 수 있다. stack 정보는 Callstack 정보이므로, 오른쪽 마우스를 Click하여 해당 stack을 Copy하여 확인하는 것이 필요할 수 있다.

by 강세윤 | 2009/02/17 15:24 | Windows debugging | 트랙백 | 덧글(0)
< 이전페이지 다음페이지 >