我有一个已加载.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不会再发生冲突,但仍然没有运气。
答案 0 :(得分:4)
这是一个非常难看的问题,并且没有简单的解决方案。核心问题是您的客户使用的CLR版本与您的版本不同。有了一些赔率,鉴于版本号大不相同,你已经安装了.NET 4.5并且客户正在使用.NET 4.0。但只是一个安全补丁足以导致不匹配,他们最近一直在稳步前进。
Afaik您几乎无法设置使用与客户使用的完全相同版本的VM或计算机。
.NET 4中的进程内并行CLR功能可以解释如何在一个进程中最终获得两个CLR版本。 v2.0版本通常用于实现COM服务器。通过添加对[ComVisible] .NET程序集的引用来避免的事情。虽然它可能不是你的代码执行此操作。祝它好运,不是一个很好的问题。
答案 1 :(得分:1)
您必须使用复杂的.cordll
命令明确加载mscordacwks.dll,这篇博文中有介绍