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

2023-11-26

我有一个转储,其中加载了两个 .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不再发生冲突,但仍然没有运气。


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

Afaik,您在设置使用以下功能的虚拟机或机器时几乎陷入困境exact与您的客户使用的版本相同。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐