5

我有一个转储,其中加载了两个 .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

=== 更新 ===

.cordll原则上是可以的。默认情况下,它将使用 .NET 4 框架。这种行为可以通过改变.cordll -I

我已经获得了与目标计算机相匹配并通过路径加载的两个版本的 SOS

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

我已从 WinDbg 6.2 升级到最新的 6.3。还是好不了。

我还问过 SOSEX 的作者 Steve Johnson,他提出了建议.cordll -I,但这在我的转储中也不起作用,无论是模块名称还是基地址。

.cordll -I clr
.cordll -I 65490000

任何尝试运行!threads总是会导致

请求 ThreadStore 失败。

任何尝试运行!clrstack总是会导致

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

=== 更新 ===

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

但是,这并不能改善分析。

=== 更新 ===

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

4

2 回答 2

4

这是一个非常丑陋的问题,而且没有简单的解决方案。核心问题是您的客户使用的 CLR 版本与您使用的不同。考虑到版本号大不相同,您可能会安装 .NET 4.5 而客户正在使用 .NET 4.0。但是仅仅一个安全补丁就足以导致不匹配,它们最近一直在稳定地出现。

Afaik,您几乎无法设置使用与客户使用的完全相同的修订版的 VM 或机器。

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

于 2013-06-21T13:21:24.907 回答
1

您将不得不使用复杂.cordll的命令来显式加载 mscordacwks.dll,这在这篇博文中有所介绍,

http://blogs.msdn.com/b/asiatech/archive/2010/09/10/how-to-load-the-specified-mscordacwks-dll-for-managed-debugging-when-multiple-net-runtime-在一个进程中加载​​.aspx

于 2013-06-25T06:08:46.623 回答