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