ASP.NET Tips: Getting SOS to work when commands fail

So the last quiz asked about a common error message you may see when debugging a dump from .NET on a machine other then where the dump was captured.  Now I want to go into more detail on this.

For a look at the quiz, check out POP QUIZ- SOS not loading properly.

History of SOS loading

So first a little background, SOS works by pulling out some globals and other data from the dump and then using this data to go find all the .NET information.  Normally, in order for this to work, you would need symbol files to find the globals.  In order to allow us to not have to have symbols to find this data, SOS in .NET Framework 1.0 created what were called BIN files.  These files contained the proper information so SOS could find all the data it needed without symbols.

sos-bin

Then, when .NET Framework 1.1 came out, we updated the framework files so that the BIN information was stored inside the mscorwks and mscorsvr files. Then we could always find the information we needed.

sos-bin2

SOS in .NET Framework 2.0

So in 2.0, we had to make some changes and there is a lot more going on then just finding globals.  Because of this, we needed a new way to get SOS working correctly.  So the mscordacwks was born.  This file is similar to the BIN files in that it is unique to the version of the framework.  So when you try to run an SOS command, if we can’t find the correct file, you will see an error like:

quiz1

There are two ways to get this to work.  The easiest is to open the dump file on the same machine as where the dump was taken from.  We will first look for this file in the directory where the framework was installed for the process being debugged.  So C:\Windows\Microsoft.Net\Framework\v2.0.50727 for example.

If you are debugging on another machine, and your framework is installed in another location, it will give you this error.

One way to work around this is to create the same folder structure as the debuggee (process being debugged) had for where the framework was installed and place the mscordacwks file in there.  If you do this, the file needs to be named with the version information in it.  So like mscordacwks_<arch>_<arch>_<version>.dll

Another way to get it to work is the place the file in a folder and make sure your symbol path points to the folder.

When you run the .cordll command, be sure to look at the paths it is looking in for the file as those are the only places where it could be and be loaded.

Filename

So what is the deal with the filename?  Well, the version information is pretty obvious, but the architecture part is not.  So these are the architecture of the debuggee (the process) and the debugger process.  That is why if you try to open a 64-bit dump in a 32-bit debugger, it will look for a file:

 mscordacwks_x86_amd64_2.0.50727.1433.dll

The first architecture is the debugger architecture and the 2nd is the debuggee architecture.  If these ever don’t match, debugging won’t work correctly.  So you only need to have a mscordacwks_x86_x86 and mscordacwks_amd64_amd64 file.  Unless you are using IA64.

Hope this clears up some of the weirdness around this file.  If any of this is unclear or you have additional questions, please feel free to ask.

kick it on DotNetKicks.com