Since .NET 2.0 is released for about a month, I think its time for me to cover a few new commands that exists in the SOS.dll WinDbg extension that comes with .NET 2.0.

First of all, the current version of WinDbg – – has an SOS.dll that can only work with .NET 1.1, so even if you do load it and try it out it will not find any .NET data in the processes since the internal .NET structures in .NET 2.0 have changed.

To start using the SOS.dll that comes with .NET 2.0 issues the following commands:

.load C:\<Windows Home Directory>\Microsoft.NET\Framework\v2.0.50727\sos.dll

If you are performing a live debug (you have attached to the process), in newer WinDbg versions you can use the following commands

.loadby sos mscorwks

This command will load the sos.dll near the mscorwks.dll that is currently loaded in the process.

Usually newer versions of WinDbg (I always recommend running the latest version of WinDbg 😉 ) contains a newer version of SOS.dll, so you should prefer to use the SOS.dll provided with WinDbg, although currently, the only SOS.dll that supports .NET 2.0 is located in the Framework’s directory, near the mscorwks.dll.

New and interesting commands

  • !dumparray – Dumps the content of an array.
    The .NET 1.1 version of SOS.dll had a !dumpcollection method which usually didn’t work for me, so it nice to have something that will dump arrays.
  • !printexception – If a parameter is given, it will dump that exception, if no parameter is given, it will dump the last exception on the stack.
    In .NET 1.1 version of SOS.dll one had to dump the stack objects, find one that is an exception and print it using !dumpobj. Now, all one has to do is call !dumpexception and the last managed exception on the current thread’s stack will be printed out.In addition to that, !dumpexception can now parse the _stackTrace field, which is a binary array if the _stackTraceString is not filled.

    !printexception will also notify you if there are nested exceptions (exceptions being thrown inside a catch handler). If you want to see those as well, use the -nested parameter.

  • !bpmd – Sets a breakpoint on managed code.
    Setting a breakpoint on a managed code prior to .NET 2.0 was very tricky. I covered this issue in a previous post.
    In that older post I only covered settings a breakpoint on an already JITed method. Setting a breakpoint on a non-JITed method is even harder. !bpmd will cover all of these aspects.To set the breakpoint all you need to do is provide the module name and method name, or the MethodDesc handle (if you have it).
    !bpmd also works on generic types. If a breakpoint is set on a generic type it will break on all derived types.

    The only way to set a breakpoint on managed code with ease before .NET 2.0 was to use CorDbg (which I covered in an previous post as well).

  • !StopOnException – stops on a particular managed exception.
    This functionality was only supported in CorDbg prior to .NET 2.0. Now, instead of breaking on every CLR exception you can specify a specific .NET exception type, such as System.ApplicationException.
  • !DumpIL – Dumps the IL code of a method.
    This was previously very hard to do. In .NET 2.0 one can always dump the IL code of a method (even at runtime).
    The main advantage here is to debug dynamic methods which are built on the fly. Its also useful for dynamically generated types (using Reflection.Emit).

As in previous version of SOS.dll, you can type !help <CommandName> to get detailed help and sometimes examples on that specific commands.

  • erdm


    i dont know if its the right place to post so sorry if its not. I have a big problem with sos extension. no mather what i do i no mater what i do i cant seem to do a bpmd. i wrote a small c# to test debuging with sos.

    class Hello
    static void Main()
    System.Windows.Forms.MessageBox.Show(“h e l l o”);

    what i do is i load the hello.exe with windbg then i wait till mscorwks.dll is loaded then i do a
    “.loadby sos mscorwks” which works fine with no errors
    “!bpmd hello.exe Hello.Main” and get the result “Adding pending breakpoints…”
    then i let it run. but it never breaks or anything. am i doing something wrong. itryed nearly everything i googled non of it helped. im using windbg: 6.8 (latest) and im sure i loaded the right sos.dll which i can confirm with this

    0:000> .chain
    Extension DLL search Path:
    C:\Program Files\Debugging Tools for Windows\WINXP;C:\Program Files\Debugging Tools for Windows\winext;C:\Program Files\Debugging Tools for Windows\winext\arcade;C:\Program Files\Debugging Tools for Windows\pri;C:\Program Files\Debugging Tools for Windows;C:\Program Files\Debugging Tools for Windows\winext\arcade;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\Intel\Wireless\Bin\
    Extension DLL chain:
    clr10\sos: image 6.8.0004.0, API 1.0.0, built Fri Sep 28 00:27:13 2007
    [path: C:\Program Files\Debugging Tools for Windows\clr10\sos.dll]
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll: image 2.0.50727.832, API 1.0.0, built Fri Apr 13 05:56:46 2007
    [path: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll]
    C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos: image 2.0.50727.832, API 1.0.0, built Fri Apr 13 05:56:46 2007
    [path: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll]
    dbghelp: image 6.8.0004.0, API 7.0.6, built Fri Sep 28 00:27:05 2007
    [path: C:\Program Files\Debugging Tools for Windows\dbghelp.dll]
    ext: image 6.8.0004.0, API 1.0.0, built Fri Sep 28 00:26:59 2007
    [path: C:\Program Files\Debugging Tools for Windows\winext\ext.dll]
    exts: image 6.8.0004.0, API 1.0.0, built Fri Sep 28 00:26:28 2007
    [path: C:\Program Files\Debugging Tools for Windows\WINXP\exts.dll]
    uext: image 6.8.0004.0, API 1.0.0, built Fri Sep 28 00:26:45 2007
    [path: C:\Program Files\Debugging Tools for Windows\winext\uext.dll]
    ntsdexts: image 7.0.6440.1, API 1.0.0, built Fri Sep 28 00:45:23 2007
    [path: C:\Program Files\Debugging Tools for Windows\WINXP\ntsdexts.dll]

    thx in advance

  • I had some problems with !bpmd myself and I have yet to figure out why.

    You can try the old school (the way it worked in 1.1), just take a look at a previous post of mine:

    This is essentially why !bpmd does for you. It might be tricky for unjitted methods, but for JITed ones its easy and it works.

  • Robert Sharp

    I am still having trouble even with all the new updates with the !bpmd. Any thoughts?