Condividi tramite


“Failed to load data access DLL, 0x80004005” – OR – What is mscordacwks.dll?

Ever seen this error in a WinDBG/CDB debug session?

Failed to load data access DLL, 0x80004005
Verify that 1) you have a recent build of the debugger (6.2.14 or newer)
            2) the file mscordacwks.dll that matches your version of mscorwks.dll is
                in the version directory
            3) or, if you are debugging a dump file, verify that the file
                mscordacwks_<arch>_<arch>_<version>.dll is on your symbol path.
            4) you are debugging on the same architecture as the dump file.
                For example, an IA64 dump file must be debugged on an IA64
                machine.

You can also run the debugger command .cordll to control the debugger's
load of mscordacwks.dll.  .cordll -ve -u -l will do a verbose reload.
If that succeeds, the SOS command should work on retry.

If you are debugging a minidump, you need to make sure that your executable
path is pointing to mscorwks.dll as well.

This error message is something that often faces people trying to debug dumps of .NET 2.0 applications using WinDBG/CDB using the SOS debugger extension. I’ve been having more than my fair share of issues with it lately and I thought it justified a bit of explanation.

What is mscordacwks.dll?

The Common Language Runtime (CLR) is the core engine of the Microsoft .NET Framework that executes managed code. In simple terms it does this by taking the intermediate language and metadata in a managed assembly, JIT compiling the code on demand, building in memory representations of the types the assembly defines and uses and ensures the resulting code is safe, secure and verifiable and gets executed when it is meant to.  This engine is itself implemented in native code. When we want to debug a .NET application using a native debugger like CDB or WinDBG (which we currently do a lot of if we want to debug it using post-mortem memory dump files) we have to use a “bridge” between the native debugger and the managed world because the native debugger does not inherently understand managed code. It is a native debugger.

To provide this bridge, the CLR helpfully ships with a debugger extension – SOS.DLL. This understands the internals of the CLR and so allows us to do things like outputting managed calls stacks, dumping the managed heap etc.

But from time to time, these internal data structures and details of the CLR change and so it is useful to abstract the interface to the CLR that this debugger extension needs from the actual internal implementation of the CLR that makes .NET applications work. Enter mscordacwks.dll. This provides the Data Access Component (DAC) that allows the SOS.DLL debugger extension to interpret the in memory data structures that maintain the state of a .NET application.

If you look in your framework folder you should always see a matching set of these 3 DLLs:

image

If you work with 64-bit you should also see a matching DLL set in the Framework64 folder.

 

What does this error message mean?

It means that the SOS.DLL debugger extension has not been able to find the matching mscordacwks.dll that it needs to be able to debug the dump file you are trying to debug.

How do you know I am debugging a dump file?

Because if you were debugging a live application the debugger extension would automatically find and load the mscordacwks.dll from the framework directory.

When am I likely to get this error message and when will I not get it?

If you are debugging a dump file from an application that was using a different build (e.g. different installed service pack or hotfix) of the CLR to the one installed on your local system, or if the .NET Framework was installed in a different location to where it is installed on your system and if the correct mscordacwks.dll is not discoverable by the debugger by some other means.

What “other means”?

Because having the matching mscordacwks.dll is so important for SOS.DLL to work correctly, SOS has a number of tricks up its sleeve to find it. In particular, provided the correct indexing to the symbol server has occurred the debugger will load it from there. The debugger will also look for it in your debuggers directory provided it has been renamed in a special way (see below).

So how do I fix it?

Most of the time, if you have your symbol path set up correctly (which you will need to anyway to make any headway at all with debugging anything, let alone managed applications) then the debugger should be able to get the correct mscordacwks.dll from the symbol server automatically:

!sym noisy
.symfix c:mylocalsymcache
.cordll -ve -u -l

What if that doesn’t work?

The simplest thing is to ask the person that gave you the dump file to look at to give you a copy of the mscordacwks.dll. Once you have it, check its file properties for the version number. It should be something like 2.0.50727.xxxx. Then rename it to

mscordacwks_AAA_AAA_2.0.50727.xxxx.dll

where xxxx is the appropriate bit of the version number and AAA is either x86 or AMD64 depending on whether you are dealing with a 32-bit or a 64-bit application dump. (The AMD64 is a legacy thing before we referred to x64). Then put this renamed copy into your debuggers directory (the one where WinDBG is installed). Then, as per the error message, tell the debugger to try again:

.cordll -ve -u -l

Although we try to ensure that every build of the CLR that is released (as a service pack, a hotfix or whatever) has its mscordacwks.dll indexed on the public symbol server, unfortunately it sometimes does not happen. But since it always ships as part of the CLR you always have the option of getting it from the machine the dump came from.

I tried the verbose logging option and it seems to be confused about whether it wants x86 or x64. Now what?

So you ran .cordll –ve –u –l as instructed and got a message something like this:

CLR DLL status: ERROR: Unable to load DLL mscordacwks_AMD64_x86_2.0.50727.3053.dll, Win32 error 0n87

What this means is that you most likely took a dump of a 32-bit process (running under WoW64) on a 64-bit system using a 64-bit debugger and you are now trying to analyse the dump using a 64-bit debugger. That's why the message references AMD64 and then x86. This is not going to work. Because the SOS.DLL extension actually makes use of the framework while debugging the bitnesses need to match. I strongly recommend always generating the dump using a debugger of the same bitness as the process (so x86 debugger for WoW64 processes even though the system is an x64 system) and analysing the dump with the same bitness of debugger that generated it. And that means of course you cannot debug a 64-bit dump on a 32-bit system. It also means you have to have the framework installed to debug a managed application dump.

Now it’s telling me it sufferred an “init failure”?

You might see this:

0:018> .cordll -ve -u -l
CLRDLL: ERROR: DLL C:WindowsMicrosoft.NETFrameworkv2.0.50727mscordacwks.dll init failure, Win32 error 0n87
CLR DLL status: ERROR: DLL C:WindowsMicrosoft.NETFrameworkv2.0.50727mscordacwks.dll init failure, Win32 error 0n87

This also points to a bitness mix up. I've seen this when using a 32-bit debugger to analyse a dump of a WoW64 process generated with a 64-bit debugger.

Isn’t this problem as old as the hills?

I am certainly not the first person to blog about this and won’t be the last either but I thought it was worth me attempting to explain some of these mysteries since it still continues to get people confused. Here are some other posts about this:

Failed to load data access DLL, 0x80004005 – hm
"Failed to start stack walk: 80004005", "Following frames may be wrong" and other errors you may see in windbg
Production Debugging for Hung ASP.Net 2 applications – a crash course
Loading CLR DAC dll from a different path

HTH

Doug

Comments

  • Anonymous
    February 18, 2009
    PingBack from http://www.clickandsolve.com/?p=10478

  • Anonymous
    December 12, 2009
    A different Error: >.cordll -ve -u -l CLRDLL: ERROR: Unsupported mscor DLL type mscoree CLR DLL status: ERROR: Unsupported mscor DLL type mscoree .NET:   4.0.21006.1 WinDbg: 6.7.0005.0 (6.11 works without needing these steps.)

  • Anonymous
    December 30, 2009
    Interesting. I can only think that CLR4  debugging needs some "hook" within WinDBG that is not there in 6.7.0005.0. I think that version is about 2.5 years old now, so well predates .NET 4.0 Doug

  • Anonymous
    February 11, 2010
    "This also points to a bitness mix up. I've seen this when using a 32-bit debugger to analyse a dump of a WoW64 process generated with a 64-bit debugger." This article says to use !wow64exts.sw to switch to 32-bit mode in this case: http://blogs.msdn.com/joaol/archive/2008/09/03/how-to-use-windbg-to-debug-a-dump-of-a-32bit-net-app-running-on-a-x64-machine.aspx

  • Anonymous
    March 23, 2011
    How does this procedure change if you are debugging a Silverlight application?

  • Anonymous
    March 23, 2011
    the debugger should be able to get the correct mscordacwks.dll from the symbol server automatically ---- My debugger can't download mscordacwks.dll from the symbol server. Why?

  • Anonymous
    March 27, 2011
    Benjamin - I'll work with you offline to figure out why this is not working for you.

  • Anonymous
    April 03, 2011
    The problem in Benjamin's case was that the symbol and mscordacwks.dll for the build in the dump he was trying to debug was not on the Microsoft public symbol server for some reason. In general it should be. If you find yourself in this situation try to upgrade to a more recent build and get a new dump. If that is not possible and debugging the dump you have is vital, contact Microsoft support.

  • Anonymous
    April 03, 2011
    Greg, for Silverlight debugging, the CLR is in coreclr.dll rather than mscorwks.dll. The other thing is that the sos.dll debugger extension does not ship with the standard Silverlight runtime. So you need to install the developer runtime. You can then grab a copy of sos.dll for that build and keep it somewhere. For example, I might rename it to sos_4_60129_0.dll (for version 4.0.60129.0 of SL) and put it in the same directory as WinDBG. I can then load it with !load sos_4_60129_0.

  • Anonymous
    December 21, 2011
    Hi, I attach to windows process where maybe use Silverlight. I get this error when i write !dumpheap -type System.String Failed to find runtime DLL (clr.dll), 0x80004005 i use your advice 1) 2) 3)  but don't go. WinDBG is 6.12.0002 version 64 bit on windows 7

  • Anonymous
    December 21, 2011
    Hi kio2008, To debug Silverlight you need to load the the SOS.DLL that comes with the Silverlight developer runtime (comes with the SDK). Sounds like you are trying to use the .NET 4.0 SOS.DLL. Also, until SL5, SL was 32-bit only. For 32-bit processes you should use 32-bit WinDBG, even on x64 Windows. HTH Doug

  • Anonymous
    April 23, 2013
    CLRDLL: ERROR: Unsupported mscor DLL type mscoree 0:004> .cordll -ve -u -l CLRDLL: ERROR: Unsupported mscor DLL type mscoree CLR DLL status: ERROR: Unsupported mscor DLL type mscoree anyone know how to fix this?

  • Anonymous
    April 23, 2013
    Hi Buddy What .loadby command did you issue to load SOS prior to getting that error? Try .loadby sos mscorwks OR .loadby sos clr  (depending on whether you are using .NET 2 or .NET 4 in the process). Are you debugging the dump on the same machine where it was generated? Doug

  • Anonymous
    January 15, 2014
    Hi Doug, just came across this issue here in a production scenario code defect situation and your post helped me to debug the dump. Once more, thanks :-) Sebastian

  • Anonymous
    January 15, 2014
    Hi Sebastian Glad to hear it helped! Hope you are keeping well and having fun. Doug

  • Anonymous
    August 13, 2014
    This seems to be true for .NET 4.0 as well. I cannot find SOS_x86_x86_4.0.30319.296.dll, for instance.

  • Anonymous
    August 17, 2014
    It's true - this error can happen in any situation where the debugger cannot get hold of the DAC for the target you are debugging.  It is possible 296 did not get indexed for some reason on the symbol server. You can always grab SOS.DLL from the machine the dump came from and rename it to the expected filename and drop it in the directory where WinDBG is