.net - studio - iis debug
Cómo depurar una excepción de stackoverflow en.NET (8)
Busque métodos que se llamen a sí mismos (o un método llame a otro y viceversa) e inspecciónelos. La recursividad suele ser el principal sospechoso cuando obtienes excepciones de SO.
Guión:
Acabo de estar en una lista e implementado un montón de código, pero cuando lo ejecuto me lanzan una StackOverflowException? StackOverflowException no tiene stacktrace así que estoy atascado. Sé por qué podría ocurrir un desbordamiento de la pila, pero para solucionarlo necesito saber dónde está la raíz.
Lo único que obtengo es una excepción no controlada del tipo ''System.StackOverflowException'' en tag-you''re-it.dll
Opciones:
- Escanee todos los cambios e intente identificar el problema. (podría ser lento)
- Use un depurador y avance hasta encontrar el problema. (Probablemente mejor que 1.)
- Use un perfil y busque los métodos más llamados.
- ?
PD:
Esta es una situación hipotética (aunque no demasiado infrecuente) y, por lo tanto, no hay código disponible.
En el método que es el "punto de entrada" a la operación que falla, coloque un punto de corte. Explore el código y observe las ocurrencias de la misma secuencia de llamadas a métodos una y otra vez en un patrón idéntico para que la pila de llamadas se haga cada vez más profunda.
Tan pronto como lo note, coloque un punto de interrupción en la ubicación actual, donde sea que esté. Continuar con la ejecución (F5 en Visual Studio): si está en el camino correcto, el depurador se detendrá rápidamente en la misma ubicación y la pila de llamadas será aún más profunda.
Ahora tiene un marco de pila "en vivo" que puede examinar, con el fin de averiguar cómo garantizar que esta recursión finalice correctamente.
Esto es casi siempre debido a la recursividad. O bien un método que se llama a sí mismo, o un método que llama a un método que lo devuelve y así sucesivamente.
Para encontrarlo:
- ACTUALIZADO : No me di cuenta, pero aparentemente no se puede obtener el rastro de la pila para una
Exception
(creo que algo tiene que ver con no poder coger uno, tampoco). Sin embargo, hay formas de obtener un volcado como se menciona aquí . - ReSharper mostrará métodos que se llaman a sí mismos (pone un pequeño círculo verde en la barra lateral para llamadas recursivas) aunque no captará la recursión cuando se trate de dos o más métodos.
- Use una herramienta como ANTS Profiler para ver qué métodos se llaman la mayoría de las veces.
- Esté atento a los eventos que se activan y que pueden llamar al código, lo que significa que el mismo evento se desencadena nuevamente, lo que provoca un bucle.
Ocasionalmente, también obtendrá errores tipográficos como este:
private string name;
public string Name
{
get { return Name; } // Ooops! This is recursive, all because of a typo...
}
Esta es una de las razones por las cuales, personalmente, ahora prefiero usar propiedades automáticas.
Personalmente, me gusta limitarlo tanto como sea posible a una determinada sección de código. Por ejemplo, acabo de tener uno. Lo curioso fue que solo estaba sucediendo en la máquina que no pude depurar directamente.
Tenía dos subprocesos ejecutándose en paralelo, de modo que detuve uno para que no se ejecutara (o podría desparealizarlo).
Luego revisé mis funciones y agregué funciones de impresión, tales como: Justo cuando la función comienza:
Console.WriteLine("<Enter method: {0}", DebuggingHelper.GetCurrentMethod());
Justo antes de que la función regrese:
Console.WriteLine(">Exit method: {0}", DebuggingHelper.GetCurrentMethod());
Donde GetCurrentMethod se define como:
[MethodImpl(MethodImplOptions.NoInlining)]
public static string GetCurrentMethod()
{
StackTrace st = new StackTrace();
StackFrame sf = st.GetFrame(1);
return sf.GetMethod().Name;
}
Luego lo ejecuto, tal vez no lo agregue a todas las funciones, pero lo suficiente como para delimitar dónde está pasando el código. Luego, dentro de esa sección, agrega más.
También puede agregar un punto de control a medida que se ejecuta a través de ciertos métodos.
Luego ejecútelo de nuevo, lo que encontrará es que la excepción ocurrirá entre esas declaraciones. Sigue estrechándote hasta que lo encuentres.
Bastante simple y rápido para encontrar dónde está pasando de esta manera.
Puede ejecutar el programa en modo de depuración y pausarlo. En la pila de llamadas actual puede ver que hay un método o un grupo de métodos que aparece varias veces, estos son los métodos problemáticos. Ponga un punto de quiebre en este método y mire cómo se llama todo el tiempo.
Si tiene el código y puede ejecutar su programa desde Visual Studio, debe interrumpir el depurador (si se activan excepciones de primera oportunidad) cuando se encuentra con System.Exception. Desde allí puede examinar la pila de llamadas y ver qué llamadas están volando la pila.
Confirmé que esto funciona para Visual Studio 2010 y Visual C # 2010 Express.
Vaya a Depurar, excepciones y marque la casilla lanzada en ''Excepciones de Common Language Runtime''. Ahora cuando causa la excepción de , el depurador se detendrá (eventualmente) y le mostrará la pila de llamadas.
WinDbg puede hacer el trabajo, incluso obtener un seguimiento de pila sensible (clr). Deberá obtener WinDbg a menos que ya lo haya instalado con Visual Studio o Windows SDK. Nota: "Vista previa de WinDbg" con la nueva GUI funcionó bien para mí.
Sugiero comenzar su proceso desde WinDbg, pero por supuesto también puede adjuntarlo a un proceso en ejecución si esto le conviene.
Nota: Justo después de iniciar el proceso, el CLR no se carga y el .loadby SOS.dll clr
fallará. Tienes que dejar que el proceso se ejecute por un tiempo y esperar a que se cargue el CLR)
Una vez que lo haya hecho, deberá realizar los siguientes pasos (ingrese la ventana / línea de comando):
- .loadby SOS.dll clr ( no .loadby sos clr - esto puede llevar a que la extensión se cargue dos veces)
- . stoponexception -create System.Exception
- g (continúa depurando)
disparar la Exception / esperar a que suceda
- ! clrstack (imprimirá stacktrace)