Debugging .Net framework source code within Windbg

One the coolest thing Microsoft did was to release the .NET Framework source code. In this post, I am going to demonstrate, how we could have a break-point on the .NET framework source code by line numbers ,using Windbg ,very similar to doing in  VS.NET.

The first step towards doing this is to download .NET Framework Source Code and installing it on the local machine. The next step is to set the symbol path environment variable. My _NT_SYMBOL_PATH is set to


SRV*d:\dev\symbols*http://referencesource.microsoft.com/symbols; SRV*d:\dev\symbols*http://msdl.microsoft.com/download/symbols

Setting the correct symbol path is important to download symbols from MS.

Here is the source code that I would be using to demonstrate this


using System;
using System.Net;
namespace Test {
 class Program {
 static void Main(string[] args) {
 Console.WriteLine("Hello World of debugging");
 var wr = WebRequest.Create("http://www.google.com");
 Console.WriteLine("Web request created");
 var req = wr.GetRequestStream();
 Console.WriteLine("Hello World Debugging");
 Console.Read();
 }
 }
}

I am going to demonstrate the same thing using multiple versions of debugger. The first one that I am going to demonstrate is using  Windows Debugger Version 6.12.0002.633 X86 which is the latest version.

Launched the exe within windbg and opened the source code WebRequest.cs and Program.cs withing Windbg.

The WebRequest.cs is the source code that was downloaded from MS Reference Source code and Program.cs is the above sample code.

Then issued the command, to be notified when mscorlib is loaded

sxe ld:mscorlib

And here is the output from the above command

ModLoad: 53fd0000 54ac8000   C:\Windows\assembly\NativeImages_v2.0.50727_32\mscorlib\8c1770d45c63cf5c462eeb945ef9aa5d\mscorlib.ni.dll
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=7efdd000 edi=0040eaf4
eip=7723fc02 esp=0040e9c8 ebp=0040ea1c iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
ntdll!ZwMapViewOfSection+0×12:
7723fc02 83c404          add     esp,4

then issued the following commands to load by sos, sosex and set break-points

.loadby sos mscorwks
.load sosex
!mbm System.Net.WebRequest.Create
!mbp WebRequest.cs 98

So with the above command I am requesting for a break-point on the method  System.Net.WebRequest.Create using symbol (!mbm). I am issuing the command !mbm ,just so that sosex can hook up with CLR for getting notifications on JIT. Without this I was unable to set break-point on source code using line numbers. The next command !mbp WebRequest.cs 98 means, have a break-point on the line number 98  in the WebRequest.cs file . The line 98 contents are “if (!useUriBase)”  .  I forgot to mention the .NET framework 4.0 source code is not released so I am using 3.5

Also make sure that the correct private pdb symbols are loaded for framework assemblies, and to verify that, issue the command “lme” and the output should contain something like this

0:000> lme
start    end        module name
013b0000 013b8000   ConsoleApplication1 C (private pdb symbols)  C:\Users\naveen\Documents\Visual Studio 2010\Projects\ConsoleApplication1\bin\Debug\ConsoleApplication1.pdb
53fd0000 54ac8000   mscorlib_ni C (private pdb symbols)  d:\dev\symbols\mscorlib.pdb\F85F3DD0C7024D528B4C37F1ACF2123D1\mscorlib.pdb
58930000 590c9000   System_ni C (private pdb symbols)  d:\dev\symbols\System.pdb\97A082CB5BC64B30887253632D3901EE1\System.pdb

And here is the output after letting it run

Breakpoint 1 hit
eax=00000001 ebx=0040f37c ecx=0282c160 edx=00000000 esi=008ba398 edi=0282c160
eip=58dec8b7 esp=0040f32c ebp=0040f334 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
System_ni+0x4bc8b7:
58dec8b7 85ff

then issued the commands to see the list of break-points (managed and native)


!mbl

bl

and here is the output

0:000> !mbl
0 e : *!SYSTEM.NET.WEBREQUEST.CREATE ILOffset=0: pass=1 oneshot=false thread=ANY
System!System.Net.WebRequest.Create(Uri, bool)+0xfffffffe(IL)
0 e 58a71630
System!System.Net.WebRequest.Create(string)
1 e 58dec8b7
System!System.Net.WebRequest.Create(Uri)+0xfffffffe(IL)
2 e 58a71600
1 eu: WebRequest.cs, line 98: pass=1 oneshot=false thread=ANY
0:000> bl
0 e 58a71630     0001 (0001)  0:**** System_ni+0×141630
1 e 58dec8b7     0001 (0001)  0:**** System_ni+0x4bc8b7
2 e 58a71600     0001 (0001)  0:**** System_ni+0×141600

because Webrequest.Create has two overloads, sosex has set a break-point on both these methods and that’s the reason we are seeing 3 break-points, instead of 2. And after issuing the “g” command for couple of hits for the Webrequest.Create , then comes the Breakpoint 3 hit. Voila ,we have the managed to set break-point on framework source code using line numbers and here is the output of  !mk command

Breakpoint 3 hit
eax=00000000 ebx=0014ecdc ecx=0282dde4 edx=00000000 esi=00000000 edi=00000000
eip=58a71650 esp=0014ec68 ebp=0014ec84 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
System_ni+0×141650:
58a71650 8bc7            mov     eax,edi
0:000> !mk
ESP      RetAddr
00:M 0014ec68 58a71650 System.Net.WebRequest.Create(System.Uri, Boolean)(+0×23 IL)(+0×0 Native) [f:\dd\ndp\fx\src\Net\System\Net\WebRequest.cs, @ 96,13]
01:M 0014ec8c 58dec8dd System.Net.WebRequest.Create(System.String)(+0×14 IL)(+0×26 Native)
02:M 0014ec9c 005000a9 Test.Program.Main(System.String[])(+0xc IL)(+0×18 Native) [C:\Users\naveen\Documents\Visual Studio 2010\Projects\ConsoleApplication1\Program.cs, @ 7,13]
03:U 0014ecb8 6cfb1b6c mscorwks!CallDescrWorker+0×33
04:U 0014ecc8 6cfc2209 mscorwks!CallDescrWorkerWithHandler+0xa3
05:U 0014ed48 6cfd6511 mscorwks!MethodDesc::CallDescr+0x19c
06:U 0014ee8c 6cfd6544 mscorwks!MethodDesc::CallTargetWorker+0x1f
07:U 0014eea8 6cfd6562 mscorwks!MethodDescCallSite::CallWithValueTypes_RetArgSlot+0x1a
08:U 0014eec0 6d040c45 mscorwks!ClassLoader::RunMain+0×223
09:U 0014f024 6d040b65 mscorwks!Assembly::ExecuteMainMethod+0xa6
0a:U 0014f28c 6d0410b5 mscorwks!SystemDomain::ExecuteMainMethod+0×456
0b:U 0014f75c 6d04129f mscorwks!ExecuteEXE+0×59
0c:U 0014f7ac 6d0411cf mscorwks!_CorExeMain+0x15c
0d:U 0014f7f4 73a461f0 mscoreei!_CorExeMain+0×38
0e:U 0014f800 74337f16 MSCOREE!ShellShim__CorExeMain+0×99
0f:U 0014f810 74334de3 MSCOREE!_CorExeMain_Exported+0×8
10:U 0014f818 74f73677 KERNEL32!BaseThreadInitThunk+0xe
11:U 0014f824 77259d72 ntdll!__RtlUserThreadStart+0×70
12:U 0014f864 77259d45 ntdll!_RtlUserThreadStart+0x1b

Notice on the top frame of the stack (00:M) we see source information. The advantage of this is, for example I can check the values of the local variable with in the function after certain calls ,which wouldn’t  have been possible without jumping hoops. Here is the the output !mdv after the line breakpoint

0:000> !mdv
Frame 0×0: (System.Net.WebRequest.Create(System.Uri, Boolean)):
[A0]:requestUri:0x282d2fc (System.Uri)
[A1]:useUriBase:0×0 (System.Boolean)
[L0]:LookupUri:<?>
[L1]:Current:null (System.Net.WebRequestPrefixElement)
[L2]:Found:0×0 (System.Boolean)
[L3]:LookupLength:<?>
[L4]:prefixList:<?>
[L5]:i:<?>
[L6]:webRequest:<?>

And my next quest was to figure What if I could use the actual break-point on the source code directly instead of using sosex.  So chose program.cs and hit the F9 key on the second Console.WriteLine and the color changed to red

And here is the output o f the bl command

0:000> bl
0 e 58a71630     0001 (0001)  0:**** System_ni+0×141630
1 e 58dec8b7     0001 (0001)  0:**** System_ni+0x4bc8b7
2 e 58a71600     0001 (0001)  0:**** System_ni+0×141600
3 e 58a71650     0001 (0001)  0:**** System_ni+0×141650
4 e 013b0017     0001 (0001)  0:**** ConsoleApplication1!Main+0×17

Notice there is a new break-point 4.  But bad luck, when i let it run it didn’t work and I had to clear the break-point 4 . It failed to create a break-point and here is the output

0:000> g
Unable to insert breakpoint 4 at 013b0017, Win32 error 0n998
“Invalid access to memory location.”
bp4 at 013b0017 failed
WaitForEvent failed
eax=00000000 ebx=0014ecdc ecx=0282dde4 edx=00000000 esi=00000000 edi=00000000
eip=58a71650 esp=0014ec68 ebp=0014ec84 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000346
System_ni+0×141650:
58a71650 8bc7            mov     eax,edi

The next step was to debug the with the version of debugger which had capabilities to see managed call stacks, Windbg version 6.7.5.0. Did the same thing loaded up the exe and the Program.cs in to the debugger and set a break-point on mscorlib load using  ” sxe ld:mscorlib” and then issued the command “.loadby sos mscorwks” ,”.load sosex” and “!mbm System.Net.WebreRequest.Create”. And the let it run, and to my surprise here is the integrated debugging experience, the source code is highlighted, when break-point is hit for WebRequest.Create

And after hitting F10 ,it moved to the next line

Wow this is way cool. The next step was to set a break-point using the bp command on the Program.cs


bp (@@masm(`Program.cs:8+`))

And  the break-point was hit and I was successfully able to have Integrated debugging environment. I know most of us don’t  have Windbg version 6.7.5.0 , but there are few debugging geeks who still have them. I was happy that I kept the version.

Take Away

We should be able to debug within the framework source code using the latest version of debugger and if you have 6.7.5.0 , can have integrated debugging experience similar to VS.NET .

About Naveen
Write code.

3 Responses to Debugging .Net framework source code within Windbg

  1. Pingback: Cheatsheet: 2010 03.08 ~ 03.14 - gOODiDEA.NET

  2. Jerome Lacube says:

    Hi Naveen,

    I’m currently very interested in trying WinDbg 6.7.5.0, and as I understood it’s gone from Internet.

    Did you still have this version ?
    If so, can you send me it or provide me with a link ?

    Anyway, Best Regards,

    Jerome Lacube

  3. Sa says:

    Hi,I am also very interested in where to get 6.7.5.0, could you please send me a link or copy?

    You know, it has been disappear after a quick fix shutting down the backdoor:(

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: