将所有字符串类型的值从托管堆转储到文件 - WinDbg

时间:2021-05-12 11:23:08

标签: .net debugging windbg

我有一个进程 (.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} }

这个命令输出:

enter image description here

但我只想将所有字符串值单独打印到一个文件中,文件内容应如下所示:

{"result":[{"user":{"abc..."
{"result":[{"user":{"zyz..."
string3
string4

在 WinDbg 中用于完成此操作的完整命令是什么?

2 个答案:

答案 0 :(得分:0)

下载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

一些变化:

  1. 同时添加字符串地址:

    !wfrom -nofield -nospace -type System.String select $addr()," ",$string()

  2. 仅转储大于 5,000 字节的字符串和地址:

    !wfrom -nofield -nospace -type System.String where (m_stringLength > 0n5000) select $addr()," ",$string()

  3. 如果字符串大于 5,000 字节,则仅打印字符串的大小和地址:

    !wfrom -nofield -nospace -type System.String where (m_stringLength > 0n5000) select $addr()," ",m_stringLength

答案 1 :(得分:0)

好吧,你可以写一个这样的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:
相关问题