¿Cómo imprimir el Stack Trace actual en .NET sin ninguna excepción?


350

Tengo un código C # normal. Tengo sin excepciones . Quiero registrar mediante programación el seguimiento de la pila actual para fines de depuración. Ejemplo:

public void executeMethod() 
{
    logStackTrace();
    method();
}

Respuestas:


400

Echa un vistazo al System.Diagnosticsespacio de nombres. Un montón de golosinas allí!

System.Diagnostics.StackTrace t = new System.Diagnostics.StackTrace();

Es realmente bueno tener un vistazo para saber qué sucede debajo del capó.

Le recomiendo que eche un vistazo a las soluciones de registro (como NLog, log4net o la Biblioteca Enterprise de patrones y prácticas de Microsoft) que pueden lograr sus propósitos y más. ¡Buena suerte compañero!


74
Tenga en cuenta que el perroStackTrace es lento , así que úselo con moderación.
Jonathan Dickinson

214

Una alternativa System.Diagnostics.StackTracees utilizar System.Environment.StackTrace, que devuelve una representación de cadena de stacktrace.

Otra opción útil es usar las variables de depuración$CALLER y $CALLSTACK en Visual Studio ya que esto se puede habilitar en tiempo de ejecución sin reconstruir la aplicación.


66
Environment.StackTracesolo nuevo es una instancia de StackTrace.
Daniel

99
@Daniel: Sí, pero System.Environment.StackTracepodría ser una forma más conveniente de acceder a esa información.
larsmoa

66
@AndreiRinea: En realidad, creo que puedes acceder a los números de línea usando System.Diagnostics.StackTrace- ver msdn.microsoft.com/en-us/library/…
larsmoa

55
¿No es molesto que Environment.StackTracesiempre comienza at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo) at System.Environment.get_StackTrace()? Eso no es parte del seguimiento de la pila actual, ya que alguien lo está buscando.
Rory

77
@Rory, eche un vistazo al constructor StackTrace (int skipFrames, bool fNeedFileInfo), puede omitir el marco inicial. Ipen el método en ILSpy y puedes ver lo que hace
Walter Vehoeven

39

Hay dos maneras de hacer esto. El System.Diagnostics.StackTrace()le dará un seguimiento de la pila para el hilo actual. Si tiene una referencia a una Threadinstancia, puede obtener el seguimiento de la pila a través de la versión sobrecargada deStackTrace() .

También es posible que desee consultar la pregunta de desbordamiento de pila ¿ Cómo obtener el stacktrace de subprocesos no actuales? .


16

También puede hacer esto en el depurador de Visual Studio sin modificar el código.

  1. Cree un punto de interrupción donde desee ver el seguimiento de la pila.
  2. Haga clic derecho en el punto de interrupción y seleccione "Acciones ..." en VS2015. En VS2010, seleccione "Al presionar ...", luego habilite "Imprimir un mensaje".
  3. Asegúrese de que "Continuar ejecución" esté seleccionado.
  4. Escriba un texto que le gustaría imprimir.
  5. Agregue $ CALLSTACK donde quiera ver el seguimiento de la pila.
  6. Ejecute el programa en el depurador.

Por supuesto, esto no ayuda si está ejecutando el código en una máquina diferente, pero puede ser bastante útil poder escupir un seguimiento de la pila automáticamente sin afectar el código de lanzamiento o incluso sin necesidad de reiniciar el programa.


77
Si desea ver un seguimiento de la pila y ya está en el depurador VS en un punto de interrupción, solo vaya a Debug-> Windows-> Call Stack.
khargoosh

55
Sí, pero si lo hace de esta manera, el programa no tiene que detenerse para que pueda ver el seguimiento de la pila.
Hank Schultz

7
Console.WriteLine(
    new System.Diagnostics.StackTrace().ToString()
    );

La salida será similar a:

en YourNamespace.Program.executeMethod (String msg)

en YourNamespace.Program.Main (String [] args)

Reemplace Console.WriteLinecon su Logmétodo. En realidad, no es necesario .ToString()el caso Console.WriteLine como lo acepta object. Pero es posible que lo necesite para su método Log (string msg).


-2
   private void ExceptionTest()
    {
        try
        {
            int j = 0;
            int i = 5;
            i = 1 / j;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            var stList = ex.StackTrace.ToString().Split('\\');
            Console.WriteLine("Exception occurred at " + stList[stList.Count() - 1]);
        }
    }

Parece funcionar para mi


3
Esto solo está generando una excepción obvia. ¿Por qué? ¿Por qué no simplemente instanciar explícitamente una excepción, en lugar de una falla que generará una excepción en sí misma? ¿Cuál es el beneficio de la lógica de captura adicional requerida para llegar a la excepción real? E incluso entonces, todavía ignora la pregunta publicada real sobre cómo obtener un seguimiento de la pila sin ninguna excepción (lea el título).
Flater

Es una respuesta válida, pero una solución horrible. NADIE DEBE USARLO ... @ Jeff donde sea que lo haya hecho, reemplácelo con un código de descenso como las otras respuestas sugeridas.
Tomer W
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.