问题描述
我有一个进程 (.Net Framework) 的进程转储,显示 OutOfMemoryException。我使用“!dumpheap -stat”查看了进程转储,并发现最大的内存消耗是“System.String”类型。
MT Count TotalSize Class Name
00007ffb081f97f8 10608868 1287368622 System.String*
为了进一步调试,我想查看所有 (10608868) 这些字符串的值。我尝试使用以下命令查看值:
.foreach (address {!DumpHeap -type System.String -short }) {!do ${address} }
这个命令输出:
但我只想将所有字符串值单独打印到一个文件中,文件内容应如下所示:
{"result":[{"user":{"abc..."
{"result":[{"user":{"zyz..."
string3
string4
在 WinDbg 中用于完成此操作的完整命令是什么?
解决方法
下载NetExt。
假设您将 NetExt 扩展名放在 c:\exts\x64(如果您将其放在其他位置,请更改示例中的文件夹)
打开转储文件并运行:
0:000> .load c:\exts\x64\netext
netext version 2.1.62.5000 Jan 29 2021
License and usage can be seen here: !whelp license
Check Latest version: !wupdate
For help,type !whelp (or in WinDBG run: '.browse !whelp')
Questions and Feedback: https://github.com/rodneyviana/netext/issues
Copyright (c) 2014-2015 Rodney Viana (http://blogs.msdn.com/b/rodneyviana)
Type: !windex -tree or ~*e!wstack to get started
0:000> !windex
Starting indexing at 10:51:12 AM
Indexing finished at 10:51:14 AM
8,581,399 Bytes in 132,086 Objects
Index took 00:00:01
0:000> .logopen c:\temp\stringsoutput.txt
Opened log file 'c:\temp\stringsoutput.txt'
0:000> !wfrom -nofield -nospace -type System.String select $string()
D:\home\site\wwwroot\
D:\home\site\wwwroot\Contoso.Sample.Web.exe.config
PARTIAL_TRUST_VISIBLE_ASSEMBLIES
Contoso.Sample.Web.exe
RELPATH
CACHE_BASE
APPBASE
DEV_PATH
DISALLOW_APP_REDIRECTS
DISALLOW_APP_BASE_PROBING
(...)
0:000> .logclose
Closing open log file c:\temp\stringsoutput.txt
一些变化:
-
同时添加字符串地址:
!wfrom -nofield -nospace -type System.String select $addr()," ",$string()
-
仅转储大于 5,000 字节的字符串和地址:
!wfrom -nofield -nospace -type System.String where (m_stringLength > 0n5000) select $addr(),$string()
-
如果字符串大于 5,000 字节,则仅打印字符串的大小和地址:
!wfrom -nofield -nospace -type System.String where (m_stringLength > 0n5000) select $addr(),m_stringLength
好吧,你可以写一个这样的javascript
:\>type foo.js
function log (instr) {
host.diagnostics.debugLog(instr +"\n");
}
function dust ()
{
var cmdstr = ".foreach (place { !DumpHeap -type String -short } ) { !do -nofields /d place }";
var objs = host.namespace.Debugger.Utility.Control.ExecuteCommand(cmdstr);
var res = [];
var k = 0;
for (i of objs)
{
if(i.includes("String:")==true)
{
log(i);
k++
}
}
log("Number of System.String = " + k.toString());
}
并像这样执行
:\>set cd
cdbx86="c:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe"
:\>file chcon.dmp
chcon.dmp: Mini DuMP crash report,17 streams,Thu May 13 10:11:26 2021,0x441826 type
:\>%cdbx86% -c "!loadby sos clr;!sosflush;.scriptload .\foo.js; dx @$scriptContents.dust();q" -z chcon.dmp | awk "/Reading/,/quit/"
0:006> cdb: Reading initial command '!loadby sos clr;!sosflush;.scriptload .\foo.js; dx @$scriptContents.dust();q'
JavaScript script successfully loaded from 'source\repos\chcon\chcon\bin\x86\Release\foo.js'
String:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
String: chcon.exe.config
String: RELPATH
String: ;
String: DYNAMIC_BASE
String: PRIVATE_BINPATH
String: SHADOW_COPY_DIRS
String: CACHE_BASE
String: APPBASE
String: DEV_PATH
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
String: .NETFramework,Version=v4.6.1
String: This is a global Test String
String: TestOne
String: Testtwo
String: ?
String: codepages.nlp
String: capacity
String: length
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
String: offset
Number of System.String = 173
@$scriptContents.dust()
quit: