WinDbg 和 SoS,如何打印/转储大字符串?

发布于 2024-10-24 05:07:35 字数 1348 浏览 7 评论 0原文

我正在使用带有 SoS 扩展的 WinDbg 调试来自生产服务器的hangdump。

其中一个堆栈中有一个字符串参数,我需要知道它的值。但是,它是一个相当大的字符串,当我使用 DumpObj 时,WinDbg 不会打印它。这是 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 <<

如何获取此字符串实例的值?最好转储到文件中。

I am debugging a hangdump coming from a production server using WinDbg with the SoS extension.

There is a string parameter in one of the stacks, that I need to know the value of. However, it is a rather large string, and WinDbg won't print it when I am using DumpObj. This is the output from 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 <<

How can I get the value of this string instance ? Preferably dumped to a file.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

◇流星雨 2024-10-31 05:07:35

这是我编写的一个脚本,用于将字符串转储到 Windbg 中的文件中。

$ 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
}

这就是它的使用方式$$>a<”c:\temp\dumpstringtofolder.txt” 6544f9ac 5000 c:\temp\stringtest

转储的内容将采用 Unicode 格式并查看它的内容使用类似这样的东西Console.WriteLine(ASCIIEncoding.Unicode.GetString(File.ReadAllBytes(@"c:\temp\stringtest03575270.txt")));

HTH

Here is a script I wrote to dump strings to a file within windbg.

$ 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
}

and this is how it can be used$$>a<”c:\temp\dumpstringtofolder.txt” 6544f9ac 5000 c:\temp\stringtest

The dumped contents would be in Unicode format and to view its contents use something like this Console.WriteLine(ASCIIEncoding.Unicode.GetString(File.ReadAllBytes(@"c:\temp\stringtest03575270.txt")));

HTH

吹梦到西洲 2024-10-31 05:07:35

在转储 2562638 个字符的文本之前,我会三思而后行,但如果您确实想要,文本将存储在字符串实例的字段之后,因此您可以执行 du

; <结束地址> 转储字符串的实际文本。输出将如下所示:

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 -"

通过将会话输出记录到文件中,您可以轻松捕获输出并执行所需的任何后处理。

I would think twice before dumping 2562638 characters worth of text, but if you really want to, the text is stored following the fields of the string instance, so you can do a du <address+offset> <end address> to dump the actual text of the string. The output will look something like this:

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 -"

By logging the session output to a file, you can easily capture the output and do whatever post-processing you need.

|煩躁 2024-10-31 05:07:35

我已经修改了 @Naveen 的脚本以在 x64 平台上工作。

顺便说一句,很棒的剧本!

$ Dumps the managed strings to a file
$ Platform x64
$ Usage $>a<"c:\temp\dumpstringtofolder.txt" 00007ffa6c509808 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
    $ 00007ffa6c50c158  400027b        8         System.Int32  1 instance               18 m_stringLength
    $ 00007ffa6c50a9c0  400027c        c          System.Char  1 instance               53 m_firstChar
    $ 00007ffa6c509808  4000280       c0        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 c-th offset
    r@$t0= (poi(${$string}+8) & 00000000FFFFFFFF) *2
    .writemem ${$arg3}${$string}.txt (${$string}+c) (${$string}+c+@$t0)
}

I have modified @Naveen's script to work on x64 platforms.

Great script btw!

$ Dumps the managed strings to a file
$ Platform x64
$ Usage $>a<"c:\temp\dumpstringtofolder.txt" 00007ffa6c509808 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
    $ 00007ffa6c50c158  400027b        8         System.Int32  1 instance               18 m_stringLength
    $ 00007ffa6c50a9c0  400027c        c          System.Char  1 instance               53 m_firstChar
    $ 00007ffa6c509808  4000280       c0        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 c-th offset
    r@$t0= (poi(${$string}+8) & 00000000FFFFFFFF) *2
    .writemem ${$arg3}${$string}.txt (${$string}+c) (${$string}+c+@$t0)
}
绿萝 2024-10-31 05:07:35

如果您赶时间,请在 WinDbg 中启用日志后运行 !do。在日志文件中,您将获得整个字符串。

在WinDbg菜单中,转到Edit->打开/关闭日志文件,设置日志文件路径。

If you are in a hurry, run the !do after enabling logs in WinDbg. In the log file, you will get the entire string.

In WinDbg menu, go to Edit-> Open/Close log file, to set log file path.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文