MANAGED DEBUGGING with WINDBG. Call Stacks. Part 3
Hi all,
This post is a continuation of MANAGED DEBUGGING with WINDBG. Call Stacks. Part 2.
CALL STACKS. Part 3
· Let's review previous commands:
Let’s see a sample where the debugger broke when “PlayWithArray” raised an exception. We can use the return address of the function it called, “mscorwks!JIT_RngChkFail”, to see where in “PlayWithArray” we were when the exception happened:
0:000> kL
ChildEBP RetAddr
0027e600 79f071ac KERNEL32!RaiseException+0x58
0027e660 79f9293a mscorwks!RaiseTheExceptionInternalOnly+0x2a8
0027e698 7a129a34 mscorwks!UnwindAndContinueRethrowHelperAfterCatch+0x70
0027e738 00371aad mscorwks!JIT_RngChkFail+0xb0
0027e780 003719fe WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[])+0x55
...
0:000> !u 00371aad
Normal JIT generated code
WindowsApplication1.Form1.PlayWithArray(Int32[])
Begin 00371a58, size c0
00371a58 55 push ebp
...
00371aa0 8b4dc8 mov ecx,dword ptr [ebp-38h]
00371aa3 3b5104 cmp edx,dword ptr [ecx+4]
00371aa6 7205 jb WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[])+0x55 (00371aad)
00371aa8 e8d67edb79 call mscorwks!JIT_RngChkFail (7a129983)
>>> 00371aad 03449108 add eax,dword ptr [ecx+edx*4+8]
00371ab1 7105 jno WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[])+0x60 (00371ab8)
00371ab3 e8837fdb79 call mscorwks!JIT_Overflow (7a129a3b)
...
00371b16 5d pop ebp
00371b17 c3 ret
0:000> u 00371aa8
WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[])+0x50 [C:\__WORKSHOP\Demos\BuggyNETApp\Form1.vb @ 135]:
...
Note how we used the unmanaged version of this command, u, to find out the source code line.
That line corresponds to the following VB.NET statement in “PlayWithArray”:
result += array(i)
It seems we got some exception when accessing the array... Can we tell why? Let’s give it a try:
0:000> !CLRStack -a
OS Thread Id: 0x1f3c (0)
ESP EIP
0027e6f0 77a1b09e [HelperMethodFrame: 0027e6f0]
0027e740 00371aad WindowsApplication1.Form1.PlayWithArray(Int32[])
PARAMETERS:
this = 0x0192f338
array = 0x01983d38
LOCALS:
0x0027e758 = 0x00000000
0x0027e754 = 0x00000006
0x0027e750 = 0x00000003
0x0027e744 = 0x00000000
0x0027e74c = 0x00000003
...
0:000> !da 0x01983d38
Name: System.Int32[]
MethodTable: 7912d7c0
EEClass: 7912d878
Size: 24(0x18) bytes
Array: Rank 1, Number of elements 3, Type Int32
Element Methodtable: 79102290
[0] 00000001
[1] 00000002
[2] 00000003
It seems we tried to access the element at index 3 of the array (the 4th element), but the array only has 3 elements.
How do I know which local corresponds to “i”? ILDASM may help here, because the locals it shows are in the same order as in !CLRStack. In our case, “i” is in the 3rd position:
// Code size 49 (0x31)
.maxstack 3
.locals init ([0] int32 PlayWithArray,
[1] int32 result,
[2] int32 i,
[3] class [mscorlib]System.Exception ex,
[4] int32 VB$CG$t_i4$S0)
· We can use registers to check parameters of a method in the call stack:
When we are at the beginning of a function, we must take into consideration that JIT compiler uses _fastcall calling convention. This means that the first two parameters will be passed in the ecx and edx registers. Ecx is used to hold the “this” pointer. We can use those registers to inspect the parameters:
0:000> g
Breakpoint 0 hit
eax=001a6e28 ebx=01ad8880 ecx=01a9f338 edx=01ada608 esi=01ada608 edi=01a9f338
eip=008f1a58 esp=002fe8a4 ebp=00000000 iopl=0 nv up ei ng nz na pe cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000287
WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[]):
008f1a58 55 push ebp
0:000> !CLRStack -p
OS Thread Id: 0x17fc (0)
ESP EIP
002fe8a4 008f1a58 WindowsApplication1.Form1.PlayWithArray(Int32[] )
PARAMETERS:
this = 0x01a9f338
array = 0x01ada608
...
002ff044 79e7c74b [GCFrame: 002ff044]
0:000> !do @ecx
Name: WindowsApplication1.Form1
...
0:000> !da @edx
Name: System.Int32[]
...
Array: Rank 1, Number of elements 3, Type Int32
...
Note that later in the function, esi is typically used to hold the “this” pointer (gotten from ecx).
Next post: MANAGED DEBUGGING with WINDBG. Threads. Part 1.
Index: MANAGED DEBUGGING with WINDBG. Introduction and Index.
Regards,
Alex (Alejandro Campos Magencio)