accessviolationexception - ¿Es posible detectar una excepción de infracción de acceso en.NET?
catch accessviolationexception (5)
Sí.
En su App.confg, coloque el siguiente código dentro de la etiqueta <configuration>
:
<runtime>
<legacyCorruptedStateExceptionsPolicy enabled="true"/>
</runtime>
Ahora debería poder detectar excepciones de estado corrupto (CSE) como cualquier otra.
Nota: Si ya tiene una etiqueta de tiempo de ejecución, simplemente agregue <legacyCorruptedStateExceptionsPolicy enabled="true"/>
a ella
Los trabajos anteriores para .Net 4.5
¿Hay algo que pueda hacer para detectar una AccessViolationException
? Está siendo lanzado por un DLL no administrado que no controlo.
Como han señalado otros, no debe "manejar" esta condición, pero durante el desarrollo es útil detectar esto por el bien de la solución de problemas.
Puede marcar su método administrado con el atributo System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions
:
[HandleProcessCorruptedStateExceptions]
public void MyMethod()
{
try
{
NaughtyCall();
}
catch (AccessViolationException e)
{
// You should really terminate your application here
}
}
En primer lugar estoy totalmente de acuerdo con 0xA3. Pero si no hay una salida, puede envolver la DLL no gestionada sucia en su propio proceso y transferir datos a través de IPC (TCP / IP, pipas con nombre, etc.). Capturar todas las excepciones e informar el proceso de host. Por lo tanto, su proceso de host se guarda principalmente de la corrupción de memoria.
No deberias Una infracción de acceso es un problema grave: es un intento inesperado de escribir (o leer) una dirección de memoria no válida. Como John ya aclaró, es posible que la DLL no administrada haya dañado la memoria del proceso antes de que se genere la infracción de acceso. Esto puede tener efectos imprevistos en cualquier parte del proceso actual.
Lo más seguro es informar al usuario y luego salir inmediatamente.
Algunos detalles más: una infracción de acceso es una excepción del sistema operativo (denominada SEH o excepción de manejo estructurado de excepciones). Este es un tipo de excepción diferente a las excepciones CLR administradas de System.Exception
. Rara vez verá las excepciones de SEH en el código puramente administrado, pero si ocurre una, por ejemplo, en el código no administrado, el CLR lo entregará al código administrado donde también puede capturarlo 1 .
Sin embargo, la captura de excepciones SEH en su mayoría no es una buena idea. Más detalles se explican en el artículo Manejo de excepciones de estado corrupto en la revista MSDN de donde proviene el siguiente texto:
El CLR siempre ha entregado excepciones SEH al código administrado utilizando los mismos mecanismos que las excepciones generadas por el propio programa. Esto no es un problema siempre que el código no intente manejar condiciones excepcionales que no pueda manejar razonablemente. La mayoría de los programas no pueden continuar la ejecución de manera segura después de una violación de acceso. Desafortunadamente, el modelo de manejo de excepciones de CLR siempre ha alentado a los usuarios a detectar estos graves errores al permitir que los programas detecten cualquier excepción en la parte superior de la jerarquía System.Exception. Pero esto rara vez es lo correcto.
1 Esto fue cierto hasta .NET 3.5. En .NET 4 el comportamiento ha sido cambiado. Si aún desea poder detectar este tipo de excepciones, tendría que agregar legacyCorruptedStateExceptionsPolicy=true
a app.config. Más detalles en los articulados vinculados anteriormente.
puede ajustar la llamada a la DLL no administrada con un bloque try-catch. AccessViolationExceptions se pueden capturar normalmente. Ejecutando el siguiente código muestra ambos mensajes:
try
{
throw new AccessViolationException();
}
catch (Exception e)
{
MessageBox.Show(e.Message + e.StackTrace, e.Message, MessageBoxButtons.OK, MessageBoxIcons.Error);
}
MessageBox.Show("Still running..");
Edición: .NET 4 introdujo un cambio en el comportamiento , ya no es posible detectar excepciones de estado dañado a menos que específicamente "ask" al tiempo de ejecución que lo haga.