¿Hay alguna forma de obtener los stacktraces para todos los subprocesos en c #, como java.lang.Thread.getAllStackTraces ()?

En Java, es posible obtener una instantánea de los stacktraces de todos los subprocesos en ejecución. Esto se hace con java.lang.Thread.getAllStackTraces() (devuelve Map ).

¿Cómo se puede hacer esto con .net?

Así que, en realidad, solo tuve que descubrir cómo hacer esto: todavía no he usado esta solución en la producción, pero hay una biblioteca relativamente nueva llamada ClrMd.

http://blogs.msdn.com/b/dougste/archive/2013/05/04/clrmd-net-crash-dump-and-live-process-inspection.aspx

Al usarlo, puedo adjuntarlo a mi propio proceso y obtener un seguimiento de stack para todos los subprocesos en vivo. Usando esto cuando se detecta un interlocking antes de reiniciar nuestra aplicación de esta manera:

 var result = new Dictionary(); var pid = Process.GetCurrentProcess().Id; using (var dataTarget = DataTarget.AttachToProcess(pid, 5000, AttachFlag.Passive)) { string dacLocation = dataTarget.ClrVersions[0].TryGetDacLocation(); var runtime = dataTarget.CreateRuntime(dacLocation); foreach (var t in runtime.Threads) { result.Add( t.ManagedThreadId, t.StackTrace.Select(f => { if (f.Method != null) { return f.Method.Type.Name + "." + f.Method.Name; } return null; }).ToArray() ); } } var json = JsonConvert.SerializeObject(result); zip.AddEntry("_threads.json", json); 

Lo realmente importante para que funcione a partir del mismo proceso es AttachFlag.Passive

Si solo haces DataTarget.AttachToProcess(pid, 5000) , hará un adjunto “invasivo” que intenta pausar el proceso. Esto produce una excepción cuando intenta adjuntar a su propio proceso, supongo que no puede pausar su aplicación al intentar adjuntar desde su aplicación o algo así.

De todos modos, sí, cosas muy interesantes.

Si alguien tiene alguna razón por la que esto es super ingenuo o algo parecido, pídales que se lo indiquen. Todavía no lo he usado mucho en la producción (solo ponga la primera instancia) así que espero que funcione.

Si desea esto solo para fines de depuración, las extensiones SOS de WinDbg pueden proporcionarle esta información.

El comando para ejecutar es “* ~ e! Clrstack”.

Dentro de un progtwig de C # en ejecución, no hay una forma pública de enumerar los hilos administrados o buscarlos por ID. Incluso si pudiera, obtener un seguimiento de stack en un subproceso diferente probablemente requiera que se suspenda, lo que conlleva algunos riesgos de efectos secundarios (vea por qué esto está obsoleto ).

La otra alternativa es enlistar los hilos como se conocen y escanearlos a su gusto. Probablemente esto solo sea posible si está creando explícitamente objetos de hilo en lugar de usar el grupo de hilos.

Dicho esto, también es difícil para mí ver a qué propósito serviría este enfoque. Si es para la depuración, hay técnicas mucho más poderosas que se pueden hacer en la memoria o en minibuses. Si es para el registro, entonces podría tener sentido que las llamadas de registro contribuyan a sus propias stacks.

Como sugiere Mason of Words, esto no parece posible desde el propio código administrado. ¿Podría aclarar por qué necesita esto: podría haber una mejor solución?

Por ejemplo, si se adjunta al proceso en Visual Studio y presiona “pausa”, la ventana “Subprocesos” mostrará una lista de todos los subprocesos administrados, y la ventana “Stacktrace” puede mostrar el seguimiento actual de la stack para cada subproceso. ¿Sería eso suficiente?

Hay una clase StackTrace

 var trace = new System.Diagnostics.StackTrace(exception); 

http://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx

Puede hacer un bucle en System.Diagnostics.Process.GetCurrentProcess (). Los subprocesos y para cada Thread crean un objeto StackTrace con el .ctor que toma un Thread como parámetro.