I usually receive a very common question when customers jump into the WinDbg adventure, and is related to the loading of SOS when the version of the .NET mismatches the version installed on their system.
The scenario is quite common, you have a customer that is running another service pack or even some random hotfix on its machine, produces a memory dump and when you try to load it on your machine you will receive this message:
Unable to load image
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll, Win32 error 2
*** WARNING: Unable to verify timestamp for mscorwks.dll
*** ERROR: Module load completed but symbols could not be loaded for mscorwks.dll
PDB symbol for mscorwks.dll not loaded
Failed to load data access DLL, 0x80004005
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.
What is happening is that the mscordacwks.dll is not matching the one loaded on the image and SOS can not be loaded.
How to solve the issue:
1) You need to ask the customer or the person that sent you the memory dump the file mscordacwks.dll localted on <Windows>\Microsoft.Net\Framework\<the .NET version (1.1, 2 or 4)> from the machine where the mem dump was produced. Note: Remember that if the customer is running 3.0 or 3.5 is still version 2 of the CLR !
2) Put that file on a separate folder (do not overwrite your one!)
3) Load the windbg and the memory dump
4) Go to File >> Symbol File Path
5) Add the folder where you copy the mscordacwks.dll file
6) Load sos.dll using the .load command
7) use !threads to see if you see the threads
What to do if the above steps do not work
The first one and probably the one that you are experiencing is that the sos is already using a different path and seems that is not using the new path. The reason is WinDbg will usually save the configuration for that memory dump, therefore it does not matter if you kill WinDbg and open it again, it will use the saved parameters. What we need to do here is to unload it and change the path. Load the dump again, and make sure you have done the steps above, then do:
1) .cordll -ve -u -l
2) You have unloaded the CLR and we are enabling the verbose mode
3) Change the CLR path using: .cordll -lp <the path where you put the mscordacwks>
4) load the SOS again
5) run !threads
There are certain scenarios where this will not work either, one can be the name of the mscordacwks.dll. Depending on the image, there may be a need to change the file name to the full version one (mscordacwks_<arch>_<version>.dll). But which one to use?
As you have enabled the verbose mode you should be able to see the full name of the mscordacwks.dll that is trying to locate, for example (mscordacwks_x86_x86_2.0.50727.3603.dll). Go back to your folder where you have put the mscordacwks.dll and rename it as indicated on the verbose output.
Repeat all the process above and it should work.
Now, if is still not working it seems that you are messing around with the steps or you have been trying a lot of things and everything is a mess. What I will recommend is the following steps to try a brand new process:
1) Close WinDBG
2) Copy the memory dump to a new location
3) Open the memory dump
4) Make sure that you have the new mscordacwks.dll (with the new name) on the new folder (last step), change the symbol paths (first step) and try again. It should work.
I hope this helps.