WinDbg и SoS, как мне печатать/выгружать большую строку?

Я отлаживаю зависание, поступающее с производственного сервера с помощью WinDbg с расширением SoS.

В одном из стеков есть строковый параметр, который должен знать значение. Однако это довольно большая строка, и WinDbg не будет печатать ее, когда я использую DumpObj. Это результат от 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 <<

Как я могу получить значение этого экземпляра строки? Предпочтительно сбрасывается в файл.

Ответ 1

Я бы подумал дважды, прежде чем сбросить 2562638 символов, но текст, но если вы действительно этого захотите, текст будет сохранен в соответствии с полями экземпляра строки, поэтому вы можете сделать 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 -"

Записывая вывод сеанса в файл, вы можете легко захватить вывод и выполнять любую последующую обработку.

Ответ 2

Вот script Я написал, чтобы сбрасывать строки в файл в 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
  [email protected]$t0=  poi(${$string}+4)*2
  .writemem ${$arg3}${$string}.txt ${$string}+8 ${$string}[email protected]$t0
}

и именно так его можно использовать $$>a<"c:\temp\dumpstringtofolder.txt" 6544f9ac 5000 c:\temp\stringtest

Сброшенное содержимое будет в формате Unicode и для просмотра его содержимого используйте что-то вроде этого Console.WriteLine(ASCIIEncoding.Unicode.GetString(File.ReadAllBytes(@"c:\temp\stringtest03575270.txt")));

НТН

Ответ 3

Если вы спешите, запустите! после включения журналов в WinDbg. В файле журнала вы получите всю строку.

В меню WinDbg перейдите в Edit- > Open/Close файл журнала, чтобы установить путь к файлу журнала.

Ответ 4

Я изменил скрипт @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
    [email protected]$t0= (poi(${$string}+8) & 00000000FFFFFFFF) *2
    .writemem ${$arg3}${$string}.txt (${$string}+c) (${$string}[email protected]$t0)
}