在.NET 2(mscorwks)和.NET 4(clr)的转储中使用SOS

时间:2013-06-21 07:30:00

标签: .net debugging windbg sos

我有一个已加载.NET版本的转储:

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) 

现在我不确定要使用哪个版本的SOS。两者都会毫无问题地加载。

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

我如何找出最适合我的分析的版本?或者我会一直需要两者吗?

在这种情况下,.cordll -ve -u -l是否可靠?

.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

线程0显示mscorwks。使用的命令:

~0s
k

=== UPDATE ===

.cordll原则上还可以。默认情况下,它将使用.NET 4框架。可以通过.cordll -I更改此行为。

我已经获得了两个版本的SOS,它们与目标计算机的版本相匹配,并由路径

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

我已经从WinDbg 6.2升级到最新的6.3。仍然没有更好。

我还问过SOSEX的作者史蒂夫约翰逊,他建议.cordll -I,但这也不适用于我的转储,既不是模块名也不是基地址。

.cordll -I clr
.cordll -I 65490000

任何运行!threads的尝试都会导致

  

无法请求ThreadStore。

任何运行!clrstack的尝试都会导致

  

无法遍历托管堆栈。当前线程可能不是托管线程。您可以运行!threads来获取进程中托管线程的列表。

=== UPDATE ===

正如Mario Hewardt所建议的那样,只需将一个SOS扩展加载到流程中(或者在已经加载的情况下卸载一个SOS扩展),就可以避免指定完整SOS路径的复杂场景,或者我们可以使用.setdll定义我们喜欢的默认SOS版本。

然而,这并没有改善分析。

=== UPDATE ===

我还尝试通过.reload /u卸载其中一个.NET模块,希望WinDbg / SOS不会再发生冲突,但仍然没有运气。

2 个答案:

答案 0 :(得分:4)

这是一个非常难看的问题,并且没有简单的解决方案。核心问题是您的客户使用的CLR版本与您的版本不同。有了一些赔率,鉴于版本号大不相同,你已经安装了.NET 4.5并且客户正在使用.NET 4.0。但只是一个安全补丁足以导致不匹配,他们最近一直在稳步前进。

Afaik您几乎无法设置使用与客户使用的完全相同版本的VM或计算机。

.NET 4中的进程内并行CLR功能可以解释如何在一个进程中最终获得两个CLR版本。 v2.0版本通常用于实现COM服务器。通过添加对[ComVisible] .NET程序集的引用来避免的事情。虽然它可能不是你的代码执行此操作。祝它好运,不是一个很好的问题。

答案 1 :(得分:1)