首先,我是不同.NET平台上的新手。
我正在尝试使用Windbg
调查托管.Net应用程序的转储(我不知道版本)。
为此,我想启动!DumpHeap -stat
命令。
最初,这不起作用,因为未加载sos
:
0:000> !DumpHeap -stat
No export DumpHeap found
0:000> .load sos
但是,似乎还有另一个问题:
0:000> !DumpHeap -stat
The garbage collector data structures are not in a valid state for traversal.
It is either in the "plan phase," where objects are being moved around, or
we are at the initialization or shutdown of the gc heap. Commands related to
displaying, finding or traversing objects as well as gc heap segments may not
work properly. !dumpheap and !verifyheap may incorrectly complain of heap
consistency errors.
Object <exec cmd="!ListNearObj /d b331dbb0">b331dbb0</exec> has an invalid method table.
在互联网上,我发现了一些帖子,其中提到此问题可能是由版本不匹配引起的,.chain
结果似乎可以证实这一点:
0:000> .chain
Extension DLL search Path:
=> Hereby my entire %PATH% environment variable
Extension DLL chain:
C:\ProgramData\dbg\sym\SOS_x86_x86_4.7.2563.00.dll\5A334E146eb000\SOS_x86_x86_4.7.2563.00.dll: image 4.7.2563.0, API 1.0.0, built Fri Dec 15 05:16:06 2017
[path: C:\ProgramData\dbg\sym\SOS_x86_x86_4.7.2563.00.dll\5A334E146eb000\SOS_x86_x86_4.7.2563.00.dll]
sos: image 4.6.1087.0, API 1.0.0, built Wed Nov 30 05:49:55 2016
[path: C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\sos.dll]
如您所见,确实确实存在版本不匹配:
C:\...\SOS (ALL CAPS) seems to be of version 4.7.2653
sos (small letters) seems to be of version 4.6.1087
让我们解决这个问题:
0:000> .unload C:\ProgramData\dbg\sym\SOS_x86_x86_4.7.2563.00.dll\5A334E146eb000\SOS_x86_x86_4.7.2563.00.dll
0:000> .load C:\ProgramData\dbg\sym\SOS_x86_x86_4.6.1087.00.dll\583E5B8E6b1000\SOS_x86_x86_4.6.1087.00.dll
// I found this file, somewhere on my PC, I just hope it's correct :-)
这可以解决问题吗?似乎不是:
0:000> !DumpHeap -stat
The garbage collector data structures are not in a valid state for traversal.
It is either in the "plan phase," where objects are being moved around, or
we are at the initialization or shutdown of the gc heap. Commands related to
displaying, finding or traversing objects as well as gc heap segments may not
work properly. !dumpheap and !verifyheap may incorrectly complain of heap
consistency errors.
Object <exec cmd="!ListNearObj /d b331dbb0">b331dbb0</exec> has an invalid method table.
好的。因此仍然没有解决方案。可能还有其他版本错误吗?
0:000> .cordll
CLR DLL status: Loaded DLL C:\ProgramData\dbg\sym\mscordacwks_x86_x86_4.7.2563.00.dll\5A334E146eb000\mscordacwks_x86_x86_4.7.2563.00.dll
的确,CLR似乎也在指该错误的版本。让我们解决一个问题:
0:000> .cordll -u
CLR DLL status: No load attempts
(首先卸载当前的,然后加载新的)
0:000> .cordll -lp C:\ProgramData\dbg\sym\mscordacwks_x86_x86_4.6.1087.00.dll\583E5B8E6b1000\mscordacwks_x86_x86_4.6.1087.00.dll
// Again a file I found somewhere on my PC, but it seems not to be working:
CLRDLL: Consider using ".cordll -lp <path>" command to specify .NET runtime directory.
CLR DLL status: ERROR: Unable to load DLL C:\ProgramData\dbg\sym\mscordacwks_x86_x86_4.6.1087.00.dll\583E5B8E6b1000\mscordacwks_x86_x86_4.6.1087.00.dll\mscordacwks_x86_x86_4.7.2563.00.dll, Win32 error 0n87
现在我没有选择了:在谷歌搜索Win32 error 0n87
时,我发现有关错误参数的信息,转储调查有误,但没有办法加载此CLR DLL。
有人可以在这里帮助我吗(也许我们可以先确定我需要选择哪个版本,我只是随机选择了一个:-))?
预先感谢
答案 0 :(得分:0)
0:000> .load sos
该命令将从WinDbg插件目录加载SOS扩展。通常,这是.NET 1.x的版本,当时该版本并未随.NET Framework安装一起提供。
.NET框架的较新版本随附有合适版本的SOS DLL。它安装在.NET Framework目录中,而不是WinDbg目录中。
稍后,我们看到上述命令已加载版本4.6.1087.0。除了文件是手动交换的以外,我真的无法解释。
垃圾收集器的数据结构处于无效的遍历状态。
如果Internet认为此可能是版本不匹配,那可能是正确的-我无法判断。
另一种选择是,该语句完全为真,并且当前正在进行垃圾回收,因此堆不一致。
第三个选项与本机代码(C ++或类似代码)有关,本机代码已写入.NET内存并破坏了一些堆信息。
[...]似乎由.chain结果确认:
因此,我们看到已加载2个版本的SOS。显然其中一个已经被加载(例如,!analyze
,您之前运行过吗?),另一个已经被.load sos
命令加载了。
让我们解决这个问题:[...]
您正在尝试使用.unload
和.load
解决问题。但是,这只会卸载一个SOS DLL,然后再次加载第二个。如果您想要一个简单的SOS版本,则应该.unload
进行2次(所有SOS DLL)访问,然后加载正确的版本。
这可以解决问题吗?似乎不是
如前所述,GC可能正在运行。您可能对以下相关问题感兴趣:How to capture a process memory dump of a .NET process when .NET is not in the middle of a garbage collection (GC)
通过查看本机调用堆栈(~*k
),应该可以弄清楚.NET当前是否在进行垃圾收集。
是不是还有其他错误版本?
实际上,CLR似乎也指的是错误的版本。
好吧,您从未确定(或至少没有告诉我们)加载到进程中的.NET版本。进行lm vm clr
可以为您提供已加载的版本(长期运行的进程例外,并且同时安装了更新,因此版本信息可能是错误的,因为它是在捕获崩溃时从磁盘读取的)转储)。
加载适当的SOS的常用命令是.loadby sos clr
,它告诉WinDbg从clr.dll所在的完全相同的位置加载SOS。如果故障转储来自您的计算机,则此方法有效。如果您从其他人那里获取故障转储,则可能会更加复杂。
.cordll -lp C:\ProgramData\dbg\sym\mscordacwks_x86_x86_4.6.1087.00.dll\583E5B8E6b1000\mscordacwks_x86_x86_4.6.1087.00.dll
-lp
代表从路径加载,但您指定了文件名。如果您看到错误消息,它会说两次mscordacwks_x86_x86_4.6.1087.00.dll
。
但是,我怀疑纠正mscordacwks是否会有所帮助-它从未抱怨过错。错误消息如下所示:
CLRDLL: [...]\mscordacwks.dll:<loaded version> doesn't match desired version <expected version>
摘要