Hi all,

This post is a continuation of MANAGED DEBUGGING with WINDBG. Setting a Breakpoint. Part 2.

 

SETTING A BREAKPOINT. Part 3

 ·        We can step through the code and do some live debugging:

When we reach a breakpoint, for instance, we can go step by step through the code as with any unmanaged application with F10 key or the following command which steps over a function:

0:000> p

 

Each step executes a single assembly instruction or a single source line, depending on whether the debugger is in assembly mode or source mode. We can change through the modes like this:

0:000> l-t

Source options are 0:

    None

0:000> l+t

Source options are 1:

     1/t - Step/trace by source line

 

If Source Mode is On and we have configured the path to the source code of the assemblies we are debugging, WinDbg will automatically open the source code file of the function where debugger just broke.

We can also step into a function with F11 or the following command:

0:000> t

 

But be careful, as this command won’t always immediately step into the function we want to. Let’s see this with a sample:

Source Mode is On and we are here:

0:000> kL

ChildEBP RetAddr 

00000000 7b062c9a WindowsApplication1!WindowsApplication1.Form1.Button6_Click(System.Object, System.EventArgs)+0x77

0028ead8 7b11cb29 System_Windows_Forms_ni!System.Windows.Forms.Control.OnClick(System.EventArgs)+0x6a

...

 

We are about to call this function:

0:000> u

WindowsApplication1!WindowsApplication1.Form1.Button6_Click(System.Object, System.EventArgs)+0x77 [C:\__WORKSHOP\Demos\BuggyNETApp\Form1.vb @ 120]:

009619ef 8b9758010000    mov     edx,dword ptr [edi+158h]

009619f5 8bcf            mov     ecx,edi

009619f7 3909            cmp     dword ptr [ecx],ecx

009619f9 e8c6a983ff      call    WindowsApplication1.Form1.PlayWithArray(Int32[]) (0019c3c4)

 

And we want to step into it:

0:000> t

WindowsApplication1.Form1.PlayWithArray(Int32[]):

0019c3c4 b8286e1900      mov     eax,196E28h

 

But wait, we didn’t reach the real code of that function yet! Actually, we are moving the Method Descriptor of our method to eax registry:

0:000> !Name2EE *!WindowsApplication1.Form1.PlayWithArray

...

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

Module: 00192c3c (WindowsApplication1.exe)

Token: 0x06000039

MethodDesc: 00196e28

Name: WindowsApplication1.Form1.PlayWithArray(Int32[])

JITTED Code Address: 00961a58

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

...

 

Note we may have to turn Source Mode Off before using “t” to go into the function, as sometimes it will step over the function instead (like the “p” command would do). I don’t know why, don’t ask ;-)

We have to continue a bit more:

0:000> p

WindowsApplication1.Form1.PlayWithArray(Int32[])+0x5:

0019c3c9 90              nop

0:000> p

WindowsApplication1.Form1.PlayWithArray(Int32[])+0x6:

0019c3ca e82197cd79      call    mscorwks!PrecodeRemotingThunk (79e75af0)

0:000> p

0019c3cf e984567c00      jmp     WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[]) (00961a58)

0:000> p

WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[]):

00961a58 55              push    ebp

 

We finally got where we wanted!

0:000> kL

ChildEBP RetAddr 

00000000 009619fe WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[])

00000000 7b062c9a WindowsApplication1!WindowsApplication1.Form1.Button6_Click(System.Object, System.EventArgs)+0x86

 

But first we had to go through some code in charge of jit compiling our method. In this case, it was already jitted so we just jumped to it.

If the method is not jitted when we step into it, we will run the following asm instead:

0:000> u

WindowsApplication1.Form1.PlayWithArray(Int32[]):

0019c3c4 b8286e1900      mov     eax,196E28h

0019c3c9 90              nop

0019c3ca e82197cd79      call    mscorwks!PrecodeRemotingThunk (79e75af0)

0019c3cf e930442e00      jmp     CLRStub[ThePreStub]@490804 (00490804)

 

We go into CLRStub[ThePreStub] method and when we reach its ret instruction, our method will be jitted and we will automatically go back to run the same asm as before (at the same memory address), but with just a “little” change:

0:000> u

WindowsApplication1.Form1.PlayWithArray(Int32[]):

0019c3c4 b8286e1900      mov     eax,196E28h

0019c3c9 90              nop

0019c3ca e82197cd79      call    mscorwks!PrecodeRemotingThunk (79e75af0)

0019c3cf e984567c00      jmp     WindowsApplication1!WindowsApplication1.Form1.PlayWithArray(Int32[]) (00961a58)

 

Now we finally jump to our method.

       

 

       

Next post: MANAGED DEBUGGING with WINDBG. Call Stacks. Part 1.

Index: MANAGED DEBUGGING with WINDBG. Introduction and Index.

 

Regards,

 

Alex (Alejandro Campos Magencio)