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

Comments (5)

  1. You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

  2. Josh Coswell says:

    Thanks for the details. Great.

    Josh Coswell

    http://riverasp.net

  3. tomchris says:

    — Question asked —

    Can you comment more about why mscordacwks.dll was created as a separate DLL instead of just compiling that info into mscorwks.dll (the way it was in .NET 1.1)?  The fact that it is a separate DLL is what causes these problems.  Why wouldn’t you want the debug binding info in mscorwks.dll?  Was it factored out just to reduce the size of mscorwks.dll?

    I ask this because I’ve run into a case where a client sent me a dump file, but now I have to ask them for their mscordacwks.dll.  I don’t have the same revision they’re running, and I haven’t seen their version before so it’s not on my symbol server.

    This is annoying to both me and my client, and I’m not even sure it’s completely legal.  If I ask a client to send me a copy of one of their core framework DLLs, aren’t they violating the .NET 2.0 EULA terms?  .NET is licensed as a supplement to the OS, but the OS license doesn’t allow you to redistribute individual files (if I’m reading all the mumbo-jumbo right).

    It would be REALLY helpful if Microsoft would make all of the mscordacwks.dll files for all .NET 2.0 revisions available for download from a single page and keep it up to date with new revisions.  Then I could grab them all and use symstore to shove them all at once into my symbol server.  The current process of trying to ask a client for the files or trying to get a server setup to just the right patch level is too much of a pain.

    — Answer —

    So this file was introduced because of the many changes that took place for sos for 2.0.  We are currently looking at options of what we can do to make it less painful.  On a plus, you should be able to get the mscordacwks files from our public symbol server.  So if you point to that, it should work correctly.  If that is not the case, please let me know.

  4. I’m trying to analyze an ASP.NET dump from one of our production web servers.  Is there a documented way to get the same version of mscordacwks that matches the system the dump came from?  I guess I could just go to that system and copy the file, but what if I were working remotely and didn’t have access to the system that the dump came from.  Does Microsoft store all of these files on their symbol server?

    Thank you,

    John

  5. tomchris says:

    John,

    There has been talk of storing those in the symbol server but I don’t know the current status of that.  I don’t think they are currently.  But I will see if I can find out.