Managed Callstack
Debugging을 위해서 사용하는 Tool은 보통 WinDBG를 사용합니다. 일반적으로 WinDBG는 Function Call의 흐름에 따른 Callstack과 각 Callstack Frame에 해당하는 Register 및 Locals의 정보를 확인할 수 있기 때문에 문제가 발생한 위치에서 정보를 verify 해 감으로써 원인을 밝혀낼 수 있도록 합니다. Managed Application의 경우는 일반적으로 WinDBG에서 Callstack이나 GC정보를 얻어낼 수 없습니다. 그래서, Microsoft는 SOS.dll이라는 Extension을 제공합니다.(http://msdn2.microsoft.com/en-us/library/ms404370.aspx) Visual Studio 2005에서 개발된 Application을 debugging 할때, WinDBG에서 가장 먼저 수행할 것은 아래의 command 입니다. 이것은 WinDBG에서 SOS extension을 사용할 수 있도록 합니다. 

.loadby SOS mscorwks

일반적으로 SOS에서 제공하는 clrstack command는 Managed Callstack을 보여줍니다. 특히, -a option을 사용하면 Locals나 parameters의 정보를 보여줍니다.

0:000> !clrstack -a
OS Thread Id: 0x464 (0)
ESP       EIP    
0012ef8c 77e0c7cd [NDirectMethodFrameStandalone: 0012ef8c]

. . .
 
0012f04c 039003b9 FCallTest.A.Foo(System.String, Int32, Int32, Int32)
PARAMETERS:
    this = 0x00c5d530
    s = 0x00c5a9ac
    param1 = 0x00000001
    param2 = 0x00000002
    param3 = 0x00000003
LOCALS:
    <CLR reg> = 0x00c5a9ac
    0x0012f050 = 0x00000001
    0x0012f054 = 0x00000002
    <CLR reg> = 0x00000003

0012f078 03900319 FCallTest.Form1.button1_Click(System.Object, System.EventArgs)
PARAMETERS:
    this = 0x00c54470
    sender = 0x00c55604
    e = 0x00c5c6d8
LOCALS:
    <CLR reg> = 0x00c5d530


. . . .

0:000> !do 0x00c5a9ac
Name: System.String
MethodTable: 02e2a3e0
EEClass: 02e2a340
Size: 30(0x1e) bytes
(C:WINDOWSassemblyGAC_32mscorlib2.0.0.0__b77a5c561934e089mscorlib.dll)
String: Hello1
Fields:
   MT    Field   Offset                 Type VT     Attr    Value Name
02e2ed1c  4000096        4         System.Int32  0 instance        7 m_arrayLength
02e2ed1c  4000097        8         System.Int32  0 instance        6 m_stringLength
02e2befc  4000098        c          System.Char  0 instance       48 m_firstChar
02e2a3e0  4000099       10        System.String  0   shared   static Empty
>> Domain:Value  00138ed8:02e06584 <<
02e54670  400009a       14        System.Char[]  0   shared   static WhitespaceChars
>> Domain:Value  00138ed8:00c51310 <<



FCallTest.exe applicaiton안의 A class에서 제공하는 Foo Method를 호출하고 있는 Callstack을 보여줍니다. 그리고 친절하게도 locals나 parameters를 볼 수 있습니다. 하지만, 간혹, Locals나 Parameters의 정보대신에 registers의 정보만을 보여주기도 합니다. 하지만, registers 정보는 유용하게 locals나 parameters의 정보를 찾을 수 있습니다. 해당 Method의 EIP값을 가지고, assembly code를 얻을 수 있습니다.

0:000> !u 039003b9
Normal JIT generated code
FCallTest.A.Foo(System.String, Int32, Int32, Int32)
Begin 03900368, size 5d
03900368 57              push    edi
03900369 56              push    esi
0390036a 53              push    ebx
0390036b 55              push    ebp
0390036c 83ec0c          sub     esp,0Ch
0390036f 890c24          mov     dword ptr [esp],ecx
03900372 8bda            mov     ebx,edx
03900374 833dc82d8c0000  cmp     dword ptr ds:[8C2DC8h],0
0390037b 7405            je      FCallTest!FCallTest.A.Foo(System.String, Int32, Int32, Int32)+0x1a (03900382)
0390037d e87c1f7976      call    mscorwks!JIT_DbgIsJustMyCode (7a0922fe)
03900382 33ff            xor     edi,edi
03900384 33d2            xor     edx,edx
03900386 89542404        mov     dword ptr [esp+4],edx
0390038a 33d2            xor     edx,edx
0390038c 89542408        mov     dword ptr [esp+8],edx
03900390 33ed            xor     ebp,ebp
03900392 90              nop
03900393 8bcb            mov     ecx,ebx
03900395 8b01            mov     eax,dword ptr [ecx]
03900397 ff5028          call    dword ptr [eax+28h]
0390039a 8bf0            mov     esi,eax
0390039c 8bfe            mov     edi,esi
0390039e 8b442428        mov     eax,dword ptr [esp+28h]
039003a2 89442404        mov     dword ptr [esp+4],eax
039003a6 8b442424        mov     eax,dword ptr [esp+24h]
039003aa 89442408        mov     dword ptr [esp+8],eax
039003ae 8b6c2420        mov     ebp,dword ptr [esp+20h]
039003b2 8bcf            mov     ecx,edi
039003b4 e8cfe89677      call    System_Windows_Forms_ni!System.Windows.Forms.MessageBox.Show(System.String) (7b26ec88)
>>> 039003b9 90              nop
039003ba 90              nop
039003bb 83c40c          add     esp,0Ch
039003be 5d              pop     ebp
039003bf 5b              pop     ebx
039003c0 5e              pop     esi
039003c1 5f              pop     edi
039003c2 c20c00          ret     0Ch


예를 들어, parameters값은 esp+28h, esp+24h, esp+20h에 저장되어 있음을 알 수 있습니다.(실제로, Assembly code 만으로 알기란 어렵습니다. !SaveModule를 이용하여 binary를 얻은 후에 reflector -http://www.aisto.com/roeder/dotnet/ -를 이용하여 Code를 같이 보는 것이 보다 쉽게 따라 갈 수 있습니다.) esp가 0012f04c 값을 가지고 있으므로, 다음과 같이 parameters의 값들을 찾을 수 있습니다.

0:000> dc 0012f04c + 28h L1
0012f074  00000001                             ....
0:000> dc 0012f04c + 24h L1
0012f070  00000002                             ....
0:000> dc 0012f04c + 20h L1
0012f06c  00000003                             ....
by SehYoon | 2006/06/26 14:02 | Windows debugging | 트랙백(1) | 핑백(2) | 덧글(0)
트랙백 주소 : http://byung.egloos.com/tb/2158371
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from 병(Byung)의 생각.. at 2006/06/26 14:51

제목 : Reflector!!
Managed Callstack 에서 보면, 단지 !u를 통해 얻어낸 assembly code만으로 코드를 이해하는 것은 쉽지 않은 일입니다. .NET은 reflection의 기능을 제공하지 때문에 Code를 역으로 generation할 수 있는 데, Reflector라는 Tool은 상당히 유용한 Tool입니다. 0:000&gt......more

Linked at Sehyoon's Weblog.. at 2007/11/04 20:59

... Managed Callstack 에서 보면, 단지 !u를 통해 얻어낸 assembly code만으로 코드를 이해하는 것은 쉽지 않은 일입니다. .NET은 reflection의 기능을 제공 ... more

Linked at 기억속으로 날다(Walking.. at 2008/10/27 14:23

... 발생한 부분을 Check 하기 위해서는 이전에 posting 된 . (간단하게) Managed Application의 Crash dump 확인하기 . Managed Callstack . FileNotFoundException를 참조하셔서 Debugging을 할 수 있습니다. ... more

:         :

:

비공개 덧글

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