2011-03-18 13 views
11

Estoy depurando un hangdump proveniente de un servidor de producción usando WinDbg con la extensión SoS.WinDbg y SoS, ¿cómo imprimo/vuelco una cadena grande?

Hay un parámetro de cadena en una de las pilas, que necesito saber el valor de. Sin embargo, es una cadena bastante grande, y WinDbg no la imprimirá cuando estoy usando DumpObj. Esta es la salida de 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 << 

¿Cómo puedo obtener el valor de esta instancia de cuerdas? Preferiblemente descargado a un archivo.

Respuesta

7

Lo pensaría dos veces antes de arrojar 2562638 caracteres de texto, pero si realmente lo desea, el texto se almacena siguiendo los campos de la instancia de cadena, por lo que puede hacer un du <address+offset> <end address> para volcar el texto real de la cadena. La salida será algo como esto:

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

Por el registro de la salida de la sesión en un archivo, puede capturar fácilmente la salida y hacer lo post-procesamiento que necesita.

+0

En el caso de cadenas realmente largas, la sintaxis de inicio de dirección/dirección final no funcionará debido a los límites. Necesita usar du L? . Para cadenas realmente largas, esto realmente llevará demasiado tiempo y WinDbg ya no responde. –

+0

Recibo el mismo mensaje en el registro que en la ventana de comandos:

+0

No entiendo. ¿Cuál es el comando que escribirías? –

13

Aquí hay un script que escribí para volcar cadenas a un archivo dentro de 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 
} 

y esta es la forma en que se puede utilizar $$>a<”c:\temp\dumpstringtofolder.txt” 6544f9ac 5000 c:\temp\stringtest

Los contenidos objeto de dumping sería en formato Unicode y para ver su contenido usar algo como esto Console.WriteLine(ASCIIEncoding.Unicode.GetString(File.ReadAllBytes(@"c:\temp\stringtest03575270.txt")));

HTH

+0

No pude conseguir que la secuencia de comandos funcionara, pero la función .writemem es lo suficientemente simple en función de su muestra. Pude hacerlo funcionar por mi cuenta. –

+0

@AndrewArnott Pude volcar cadena usando este script y lo uso a menudo. ¿Cuál fue el problema con el que te topabas? ¿Lo estás usando en x86/x64? – Naveen

+1

No estoy seguro si podemos confiar en la salida de! Name2EE pero esto se puede utilizar para obtener el puntero de tabla de método automáticamente (r @ $ t1), por lo que podríamos deshacernos del parámetro 1. .foreach/pS 7/ps 4 (methodtable {! Name2EE mscorlib.dll System.String}) {r @ $ t1 = $ {methodtable}} –

1

Si está con prisa, ejecute! do después de habilitar los registros en WinDbg. En el archivo de registro, obtendrá la cadena completa.

En el menú WinDbg, vaya a Edición-> Abrir/Cerrar archivo de registro, para establecer la ruta del archivo de registro.

+0

Acabo de obtener la misma cadena truncada en el archivo de registro. Solo FYI ... – Jace

+1

Recibo el mismo mensaje en el registro que en la ventana de comandos:

Cuestiones relacionadas