咨询区

  • driis

我在用 windbg 调试一个生产上的 ​​程序卡死​​​ 故障 ,在线程栈上有一个 ​​string​​​ 类型的参数相当大,我用 ​​!dumpobj​​ 命令不能正常显示内容,参考如下:

0:036> !do 00000001b30d8668
Name: System.String
MethodTable: 0000064278436728
EEClass: 000006427803e520
Size: 5125300(0x4e34b4) bytes
(C:\WINDOWS\assembly\GAC_64\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll)
String: <String is invalid or too large to print>

Fields:
MT Field Offset Type VT Attr Value Name
000006427843d998 4000096 8 System.Int32 1 instance 2562638 m_arrayLength
000006427843d998 4000097 c System.Int32 1 instance 2562637 m_stringLength
0000064278438170 4000098 10 System.Char 1 instance 3c m_firstChar
0000064278436728 4000099 20 System.String 0 shared static Empty
>> Domain:Value 0000000000163260:000000007fff0370 00000000001a6760:000000007fff0370 <<
0000064278438020 400009a 28 System.Char[] 0 shared static WhitespaceChars
>> Domain:Value 0000000000163260:000000007fff0b60 00000000001a6760:000000007fff89f0 <<

请问我该如何将 string 内容导出来,如果能导出到文件中就更好了。

回答区

  • Naveen

下面是一个可以将 string 导出到 文本的脚本,你可以试试看。

$$ Dumps the managed strings to a file
$$ Platform x86
$$ Usage $$>a<"c:\temp\dumpstringtofolder.txt" 6544f9ac 5000 c:\temp\stringtest
$$ First argument is the string method table pointer
$$ Second argument is the Min size of the string that needs to be used filter
$$ the strings
$$ Third is the path of the file
.foreach ($string {!dumpheap -short -mt ${$arg1} -min ${$arg2}})
{

$$ MT Field Offset Type VT Attr Value Name
$$ 65452978 40000ed 4 System.Int32 1 instance 71117 m_stringLength
$$ 65451dc8 40000ee 8 System.Char 1 instance 3c m_firstChar
$$ 6544f9ac 40000ef 8 System.String 0 shared static Empty

$$ start of string is stored in the 8th offset, which can be inferred from above
$$ Size of the string which is stored in the 4th offset
r@$t0= poi(${$string}+4)*2
.writemem ${$arg3}${$string}.txt ${$string}+8 ${$string}+8+@$t0
}

接下来就可以用如下命令将其导出到 ​​c:\temp\stringtest​​ 文件中。

$$>a<”c:\temp\dumpstringtofolder.txt” 6544f9ac 5000 c:\temp\stringtest

需要提一下的是 C# 中的 string 内容是 unicode 格式,你用文本文件打开的时候注意改成 unicode 。

  • Brian Rasmussen

你可以用 ​​du​​ 命令查看内存地址的内容,格式如下:

du <address+offset> <end address>

输出内容大概如下:

00000000`132ab050  "this is an extremely long string"
00000000`132ab090 " of text, so don't even bother t"
00000000`132ab0d0 "o try to dump it to the screen -"

点评区

这是在 ​​高级调试​​​ 中经常会遇到的问题,我个人的用法还是 ​​.writemem startaddress L?length​​  模式,这里我举个例子:

0:000> !do -nofields 000001eb2a587cf8
Name: System.String
MethodTable: 00007ffc403d6948
EEClass: 00007ffc3fcd50e0
Size: 38(0x26) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: 小容量注射液

可以看到当前内容是 ​​小容量注射液​​​ ,length 是 ​​0x26​​ ,所以导出命令就是:

0:000> .writemem C:\1.txt 000001eb2a587cf8 L?0x26 
Writing 26 bytes.

可以看到已经成功写入 ​​26byte​​。

如何用 windbg 导出 C# 中的 string 内容?_ico