Thursday 3 June 2010

Setting a breakpoint in Windbg at the beginning of the Main method of a .Net application

I thought it was easy to set a breakpoint at the beginning of the main method of a .net application.

Indeed it is not trivial and since i was in troubles, as usual, i started to dig the Internet for a help.

I found these 2 articles:
http://blogs.msdn.com/b/tess/archive/2008/06/05/setting-net-breakpoints-in-windbg-for-applications-that-crash-on-startup.aspx
and
http://blogs.msdn.com/b/mahuja/archive/2008/07/16/managed-debugging-and-inspecting-jitted-code-with-windbg.aspx

The first is by Tess Ferrandez, author of many excellent posts about the debugging of .net applications.
Unfortunately I was not able to set a breakpoint on the main method with that tecnique.It's almost sure that I'm doing something wrong since Ferrandez's experience is by far greater than mine :-) .

The second article allowed me to do what i wanted to do. The article is by Madhur.

I strongly suggest to read that article!

The only thing I can say is that it' not mandatory to follow all the steps described there.

I managed to obtain the result in this way:

1) Open Windbg.

2) Open the executable (Ctrl+E and search the .exe).

3) at the prompt type 'sxe ld:mscorjit'
this is the key of Madhur's article and tells to Windbg to set a breakpoint as soon the the jitting engine (mscorjit.dll) is loaded into memory.

4) than type 'g' to let go the Application since the breakpoint is hit.

5) type '.loadby sos mscorwks' to load the sos extension necessary to use a command of the next.

6) type '.sympath srv*;C:\Projects\ApplicationTest\ApplicationTest\bin\Debug' (changing the path accordingly with the one of your application) and then '.reload' to make the symbols informations available to the debugger.

7) type '!name2ee ApplicationTest ApplicationTest.Program.Main' changing ApplicationTest with the name of the module of your application. This command will tell you that the Main method has not been Jiited yet and to use '!bpmd -md' + the suggested method descriptor to set the desired breakpoint.

8) type the !bpmd command and then type 'g' and wait for the breakpoint being hit.

At this point the execution stops at the beginning of the main method and you can confirm this typing the command 'clrstack -a'.

What follows is the Windbg debugging session text:
   1 CommandLine: C:\Projects\ApplicationTest\ApplicationTest\bin\Debug\ApplicationTest.exe
2 Symbol search path is: srv*;C:\Projects\ApplicationTest\ApplicationTest\bin\Debug
3 Executable search path is:
4 (1568.1078): Break instruction exception - code 80000003 (first chance)
5 eax=00000000 ebx=00000000 ecx=003cf618 edx=779a64f4 esi=fffffffe edi=00000000
6 eip=779fe60e esp=003cf634 ebp=003cf660 iopl=0 nv up ei pl zr na pe nc
7 cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
8 ntdll!LdrpDoDebuggerBreak+0x2c:
9 779fe60e cc int 3
10 0:000> sxe ld:mscorjit
11 0:000> g
12 ModLoad: 72470000 724cb000 C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll
13 eax=6fe74bb8 ebx=00000000 ecx=00252ffc edx=000e0e3c esi=7ffdf000 edi=003ce500
14 eip=779a64f4 esp=003ce418 ebp=003ce46c iopl=0 nv up ei pl zr na pe nc
15 cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
16 ntdll!KiFastSystemCallRet:
17 779a64f4 c3 ret
18 0:000> .loadby sos mscorwks
19 0:000> .sympath srv*;C:\Projects\ApplicationTest\ApplicationTest\bin\Debug
20 Symbol search path is: srv*;C:\Projects\ApplicationTest\ApplicationTest\bin\Debug
21 Expanded Symbol search path is: cache*;SRV*http://msdl.microsoft.com/download/symbols;c:\projects\applicationtest\applicationtest\bin\debug
22 0:000> .reload
23 Reloading current modules
24 .........................
25 0:000> !name2ee ApplicationTest ApplicationTest.Program.Main
26 Module: 00252c5c (ApplicationTest.exe)
27 Token: 0x06000001
28 MethodDesc: 00252ffc
29 Name: ApplicationTest.Program.Main(System.String[])
30 Not JITTED yet. Use !bpmd -md 00252ffc to break on run.
31 0:000> !bpmd -md 00252ffc
32 MethodDesc = 00252ffc
33 Adding pending breakpoints...
34 0:000> g
35 (1568.1078): CLR notification exception - code e0444143 (first chance)
36 JITTED ApplicationTest!ApplicationTest.Program.Main(System.String[])
37 Setting breakpoint: bp 004C0070 [ApplicationTest.Program.Main(System.String[])]
38 Breakpoint 0 hit
39 eax=00252ffc ebx=003cef6c ecx=018d8fac edx=00000000 esi=000c6fb8 edi=00000000
40 eip=004c0070 esp=003cef44 ebp=003cef50 iopl=0 nv up ei pl nz ac po nc
41 cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000212
42 004c0070 55 push ebp
43 0:000> !clrstack -a
44 OS Thread Id: 0x1078 (0)
45 ESP EIP
46 003cef44 004c0070 ApplicationTest.Program.Main(System.String[])
47 PARAMETERS:
48 args = 0x018d8fac
49 LOCALS:
50 <no data>
51 <no data>
52 <no data>
53
54 003cf15c 6f931b6c [GCFrame: 003cf15c]
58