unauthorizedaccessexception - C#captura una excepción de desbordamiento de pila
system stackoverflowexception error en c# (9)
Recibí una llamada recursiva a un método que arroja una excepción de desbordamiento de pila. La primera llamada está rodeada por un bloque try catch pero la excepción no está atrapada.
¿La excepción de desbordamiento de pila se comporta de una manera especial? ¿Puedo capturar / manejar correctamente la excepción?
NB: si es relevante:
la excepción no se arroja en el hilo principal
el objeto donde el código arroja la excepción es cargado manualmente por Assembly.LoadFrom (...). CreateInstance (...)
Comenzando con 2.0, una excepción de solo puede capturarse en las siguientes circunstancias.
- El CLR se está ejecutando en un entorno alojado donde el host permite específicamente que se manejen las excepciones de
- La excepción de es lanzada por el código de usuario y no debido a una situación real de desbordamiento de la pila ( Reference )
Como se mencionó anteriormente varias veces, no es posible detectar una Exception que el sistema ha provocado debido a un estado de proceso dañado. Pero hay una manera de notar la excepción como un evento:
http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspxComenzando con .NET Framework versión 4, este evento no se plantea para excepciones que corrompen el estado del proceso, como desbordamientos de pila o violaciones de acceso, a menos que el controlador de eventos sea crítico para la seguridad y tenga el atributo HandleProcessCorruptedStateExceptionsAttribute.
Sin embargo, su aplicación terminará después de salir de la función de evento (una solución MUY sucia, fue reiniciar la aplicación dentro de este evento jaja, no lo ha hecho y nunca lo hará). ¡Pero es lo suficientemente bueno para iniciar sesión!
En .NET Framework versiones 1.0 y 1.1, el tiempo de ejecución atrapa una excepción no controlada que ocurre en un hilo que no sea el hilo de la aplicación principal y, por lo tanto, no causa que la aplicación finalice. Por lo tanto, es posible que el evento UnhandledException se produzca sin que la aplicación finalice. Comenzando con .NET Framework versión 2.0, este tope para excepciones no controladas en subprocesos hijo se eliminó porque el efecto acumulativo de tales fallas silenciosas incluía degradación del rendimiento, datos dañados y bloqueos, todos los cuales eran difíciles de depurar. Para obtener más información, incluida una lista de casos en los que el tiempo de ejecución no finaliza, consulte Excepciones en hilos gestionados.
Como ya han dicho varios usuarios, no se puede detectar la excepción. Sin embargo, si estás luchando por descubrir dónde está sucediendo, es posible que desees configurar Visual Studio para que se rompa cuando se lanza.
Para hacerlo, debe abrir Configuración de excepciones en el menú ''Depurar''. En versiones anteriores de Visual Studio, esto está en ''Depurar'' - ''Excepciones''; en versiones más nuevas, está en ''Depurar'' - ''Windows'' - ''Configuración de excepción''.
Una vez que tenga la configuración abierta, expanda ''Excepciones de Common Language Runtime'', expanda ''Sistema'', desplácese hacia abajo y marque ''System.Exception''. Luego puede mirar la pila de llamadas y buscar el patrón repetitivo de llamadas. Eso debería darte una idea de dónde buscar para corregir el código que causa el desbordamiento de la pila.
Desde la página MSDN en Exception s:
En versiones anteriores de .NET Framework, su aplicación podría capturar un objeto Exception (por ejemplo, para recuperarse de la recursión ilimitada). Sin embargo, esa práctica actualmente se desaconseja porque se requiere un código adicional significativo para capturar de manera confiable una excepción de desbordamiento de pila y continuar la ejecución del programa.
Comenzando con .NET Framework versión 2.0, un objeto de prueba-captura no puede capturar un objeto Exception y el proceso correspondiente finaliza de forma predeterminada. En consecuencia, se recomienda a los usuarios que escriban su código para detectar y evitar un desbordamiento de la pila. Por ejemplo, si su aplicación depende de la recursión, use un contador o una condición de estado para terminar el ciclo recursivo. Tenga en cuenta que una aplicación que aloja el Common Language Runtime (CLR) puede especificar que CLR descargue el dominio de la aplicación donde se produce la excepción de desbordamiento de la pila y permita que el proceso correspondiente continúe. Para obtener más información, consulte ICLRPolicyManager Interface y Hosting Common Language Runtime.
Es imposible, y por una buena razón (para uno, piense en todas esas capturas (Excepción) {} alrededor).
Si desea continuar la ejecución después del desbordamiento de la pila, ejecute el código peligroso en un Dominio de aplicación diferente. Las políticas de CLR pueden configurarse para terminar el dominio de aplicación actual en desbordamiento sin afectar el dominio original.
La forma correcta es arreglar el desbordamiento, pero ...
Puedes darte una pila más grande:
using System.Threading;
Thread T = new Thread(threadDelegate, stackSizeInBytes);
T.Start();
Puede usar la propiedad System.Diagnostics.StackTrace FrameCount para contar los cuadros que ha utilizado y lanzar su propia excepción cuando se alcanza un límite de cuadro.
O bien, puede calcular el tamaño de la pila restante y lanzar su propia excepción cuando caiga por debajo de un umbral: -
class Program
{
static int n;
static int topOfStack;
const int stackSize = 1000000; // Default?
// The func is 76 bytes, but we need space to unwind the exception.
const int spaceRequired = 18*1024;
unsafe static void Main(string[] args)
{
int var;
topOfStack = (int)&var;
n=0;
recurse();
}
unsafe static void recurse()
{
int remaining;
remaining = stackSize - (topOfStack - (int)&remaining);
if (remaining < spaceRequired)
throw new Exception("Cheese");
n++;
recurse();
}
}
Solo atrapa el queso. ;)
No puedes, como la mayoría de las publicaciones están explicando, déjame agregar otra área:
En muchos sitios web encontrarás personas que dicen que la forma de evitar esto es usar un dominio de aplicación diferente, de lo contrario, el dominio se descargará. Eso es absolutamente incorrecto (a menos que usted aloje su CLR) ya que el comportamiento predeterminado del CLR generará un evento KillProcess, derribando su AppDomain predeterminado.
No puedes. El CLR no te dejará. Un desbordamiento de pila es un error fatal y no se puede recuperar.
Sí, desde el desbordamiento de la pila CLR 2.0 se considera una situación no recuperable. Entonces, el tiempo de ejecución todavía cerró el proceso.
Para obtener detalles, consulte la documentación Exception