Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SOS in a dump with .NET 2 (mscorwks) and .NET 4 (clr)

I have a dump which has both .NET versions loaded:

0:000> lm m clr
start    end        module name
65490000 65aff000   clr        (deferred)             
0:000> lm m mscorwks
start    end        module name
6a980000 6af2c000   mscorwks   (deferred) 

Now I'm uncertain which version of SOS to use. Both will load without problems.

0:000> .loadby sos mscorwks
0:000> .loadby sos clr

How would I find out which version to use best for my analysis? Or will I always need both?

Is .cordll -ve -u -l reliable in this case?

.symfix c:\symbols
.cordll -ve -u -l

CLRDLL: C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscordacwks.dll:4.0.30319.18047 f:8
doesn't match desired version 4.0.30319.296 f:8
CLRDLL: Loaded DLL c:\symbols\mscordacwks_x86_x86_4.0.30319.296.dll\50484AA966f000\mscordacwks_x86_x86_4.0.30319.296.dll
CLR DLL status: Loaded DLL c:\symbols\mscordacwks_x86_x86_4.0.30319.296.dll\50484AA966f000\mscordacwks_x86_x86_4.0.30319.296.dll

Thread 0 shows mscorwks. Commands used:

~0s
k

=== UPDATE ===

.cordll in principle is ok. By default it will use .NET 4 framework. This behavior can be changed by .cordll -I.

I have obtained both versions of SOS which match that of the target computer and loaded by path

.load C:\SOS\4.0.30319.296\SOS.dll

I have upgraded from WinDbg 6.2 to latest 6.3. Still not better.

I have also asked Steve Johnson, the author of SOSEX who suggested .cordll -I, but this also does not work in my dump, neither with module name nor with base address.

.cordll -I clr
.cordll -I 65490000

Any attempt to run !threads always results in

Failed to request ThreadStore.

Any attempt to run !clrstack always results in

Unable to walk the managed stack. The current thread is likely not a managed thread. You can run !threads to get a list of managed threads in the process.

=== UPDATE ===

As suggested by Mario Hewardt, the complex scenario with specifying the full SOS path can be avoided by only loading one SOS extension into the process (or unloading one in case they are already loaded) or we can use .setdll to define the default SOS version we like.

However, this does not improve the analysis.

=== UPDATE ===

I have also tried unloading one of the .NET modules by .reload /u in the hope that WinDbg/SOS would not be in a conflict any more, but still no luck.

like image 267
Thomas Weller Avatar asked Jun 21 '13 07:06

Thomas Weller


2 Answers

This is a very ugly problem and afaik there is no simple solution for it. The core issue is that your customer uses a different revision of the CLR than you do. With some odds, given the wildly different revision numbers, that you've got .NET 4.5 installed and the customer is using .NET 4.0. But just a security patch can be enough to cause a mismatch, they've been coming in steadily of late.

Afaik you are pretty much stuck setting up a VM or machine that uses the exact same revision as your customer uses.

The in-process side-by-side CLR feature in .NET 4 can otherwise explain how you could end up with two CLR versions in one process. The v2.0 version would typically be there to implement a COM server. Something you avoid by adding a reference to the [ComVisible] .NET assembly instead. Albeit that it may well not be your code that does this. Good luck with it, not a nice problem to have.

like image 167
Hans Passant Avatar answered Sep 22 '22 22:09

Hans Passant


You will have to use complex .cordll commands to load the mscordacwks.dll explicitly, which is covered in this blog post,

http://blogs.msdn.com/b/asiatech/archive/2010/09/10/how-to-load-the-specified-mscordacwks-dll-for-managed-debugging-when-multiple-net-runtime-are-loaded-in-one-process.aspx

like image 42
Lex Li Avatar answered Sep 20 '22 22:09

Lex Li