2010-04-27 12 views
21

Estoy depurando un problema aparente de concurrencia en una aplicación bastante grande que pirateé en el trabajo. El error en cuestión solo se manifiesta en ciertas máquinas de bajo rendimiento después de funcionar durante muchas (12+) horas, y nunca lo he reproducido en el depurador. Debido a esto, mis herramientas de depuración están básicamente limitadas al análisis de archivos de registro.¿Puedo obtener los rastros de la pila de todos los hilos en mi aplicación C#?

C# hace que sea fácil obtener el rastro de pila del hilo arrojando la excepción, pero me gustaría obtener adicionalmente los rastros de pila de cada otro hilo que se esté ejecutando actualmente en mi AppDomain en el momento en que se lanzó la excepción.

¿Esto es posible?

+3

Estaba buscando algo así el otro día (y me encontré con esta pregunta: http://stackoverflow.com/questions/190236/how-do-i-make-a-thread-dump-in- net-a-la-jvm-thread-dumps). Parece que no tiene suerte, pero sigue siendo bueno ver lo que los que respondieron a esa pregunta tenían que decir. –

+0

Gracias Dan, saqué algunas cosas bastante útiles de tu pregunta vinculada ... –

Respuesta

5

Hay una herramienta en CodePlex llamada Managed Stack Explorer (que creo que se originó en Microsoft). Utiliza la API de depuración y creación de perfiles para capturar los restos de pila de los subprocesos en una aplicación .Net en ejecución, sin la necesidad de modificar la aplicación.

Puede ejecutar su aplicación hasta que experimente el problema, luego analice usando esta herramienta para capturar los trazados de pila actuales de todos los subprocesos en ejecución. El beneficio de este enfoque es que deja su aplicación sin modificar (instrumentando que puede cambiar su comportamiento), y la herramienta es gratuita.

+0

Esta parece la mejor solución. Sin duda sería bueno si el marco lo soportara de forma nativa dentro del lenguaje, aunque ... –

+4

No crea que ya sea compatible con .NET4, incluso la aplicación de muestra no aparece en la lista en una PC con .NET4 instalado . – angularsen

4

Sugiero tomar un volcado del proceso cuando se produce la excepción. En el mismo lugar donde está registrando la excepción, llame al método MakeDumpFile() como se muestra a continuación.

Esto supone que tiene Debugging Tools For Windows instalado en la máquina problemática.

private static void MakeDumpFile() 
    {    
     int pid = Process.GetCurrentProcess().Id; 
     Console.WriteLine("Creating dump for pid " + pid); 

     //path to adplus executable; ensure you have Debugging tools installed; 
     string program = @"C:\Program Files (x86)\Debugging Tools for Windows (x86)\adplus.exe"; 

     //args for adplus; ensure the crashdump folder exists! 
     string args = string.Format(@"-hang -p {0} -o c:\crashdump", pid); 

     var startInfo = new ProcessStartInfo(program, args); 
     startInfo.UseShellExecute = false; 
     startInfo.ErrorDialog = false; 
     startInfo.CreateNoWindow = true; 
     startInfo.RedirectStandardOutput = true; 

     var process = Process.Start(startInfo); 
     Console.WriteLine("The following is output from adplus"); 
     Console.WriteLine(process.StandardOutput.ReadToEnd()); 
     Console.WriteLine("Finished creating dump."); 
    } 

Navegue hasta el directorio de volcado y debería ver una nueva carpeta con un archivo en él nombró FULLDUMP_something_.dmp.

Si usted está en .NET4 puede simplemente arrastrar esto en VS2010 y echa un vistazo a todos los hilos o utilizar hilos paralelos para ver lo que está pasando (esto es impresionante!)

Si en NET3.5 o antes necesitarás usar windbg para analizar. Utilice el siguiente comando

~ * e! Clrstack

para imprimir la pila de llamadas de todos los subprocesos administrados. Si necesita más ayuda, windbg going post back o google para obtener un tutorial.

+0

Cuando instalé las herramientas de depuración, encontré que la ruta de instalación era: C: \ Archivos de programa \ Windows Kits \ 8.1 \ Debuggers \ x86 – Charlie

Cuestiones relacionadas