2010-06-01 12 views
10

pregunta real (s):¿Qué sucede en el nivel del sistema operativo cuando un programa .net se cierra debido a una excepción no detectada?

¿Qué ocurre "en Windows" cuando un programa se bloquea de una excepción no capturada?

¿Hay una función dll, que puedo conectar, para registrar información básica sobre un bloqueo?

Contexto:

Tengo la intención de escribir un programa que recogerá información muy básica sobre todas las aplicaciones que accidente en mi PC local. Tenía la esperanza de poder ejecutar un método simple para registrar información sobre un bloqueo de una manera similar a la forma en que Visual Studio produce un diálogo que ofrece para permitirle depurar un programa cuando falla.

+1

Su pregunta no parece ser específica de .net ya que una gran parte de la aplicación en su PC local no son necesariamente aplicaciones .net. – shoosh

+0

Sí, tienes razón. Solo para aclarar, estoy más interesado en los bloqueos causados ​​por las aplicaciones .net porque es más probable que hayan sido causados ​​por mí. – Richard

+1

AFAIK, una excepción .Net no detectada no es un bloqueo. Se produce un bloqueo cuando el sistema operativo detecta una excepción SEH y llama a TerminateProcess. El CLR atrapa una excepción .Net y causa una llamada a ExitProcess, una salida mucho más agradable. – MSalters

Respuesta

5

Las excepciones administradas se implementan utilizando los mecanismos normales de Windows Structured Exception Handling. El código de excepción es 0xe0434f4d. Windows busca un manejador de excepciones que esté dispuesto a manejar la excepción. Si el código no tiene un bloque try activo en la pila, o si ningún bloque catch está dispuesto a atrapar la excepción gestionada, el último grito de sorpresa en el código administrado es el evento AppDomain.UnhandledException.

Si eso no se implementa, ya sea que el manejo de excepciones cambie a un manejo no administrado, un filtro de excepción establecido con SetUnhandledExceptionFilter obtiene una oportunidad. En su defecto, siempre hay un controlador predeterminado proporcionado por Windows. Normalmente invoca WER, el programa de informe de errores de Windows. Eso ofrece al usuario un diálogo para enviar los detalles de la excepción a Microsoft. No esperes nada de eso.

En el momento en que ha progresado más allá de AppDomain.UnhandledException, se pierde toda la información sobre la excepción administrada. Sin seguimiento de pila, sin mensaje de excepción. Solo el código de excepción, que ya conoce, y una dirección de excepción, que no tendrá uso alguno porque el compilador JIT genera dinámicamente el código.

Asegúrese de atrapar la excepción en la última etapa de jadeo, escriba un controlador de eventos para AppDomain.UnhandledException. Registre el valor de e.ExcdeptionObject.ToString() y elimine el programa con Environment.Exit(). También tenga cuidado con el evento Application.ThreadException en el código de Windows Forms y en el evento Dispatcher.UnhandledException en el código WPF. Son una parada para las excepciones que surgen durante el procesamiento de eventos en el hilo de la interfaz de usuario.

2

Para aplicaciones nativas se pueden utilizar las siguientes funciones:

Además, puede utilizar AddVectoredExceptionHandler aunque no lo recomendaría ya que también intercepta las excepciones detectadas.

El puntero a función que pasa a SetUnhandledExceptionFilter obtiene una estructura como argumento de entrada, que contiene toda la información sobre la excepción (razón, registros, ...).

En mi aplicación utilizo SetUnhandledExceptionFilter para crear un volcado de aplicación (usando la función MiniDumpWriteDump desde DBGHELP.DLL dll) si la aplicación falla. Tenga cuidado de no hacer demasiado en esa función. Debido a que su aplicación ya se bloquea, no se garantiza que ninguna otra lógica funcione (por ejemplo, el acceso a sus propias estructuras de datos, que podrían ser correctas, puede causar más bloqueos).

Considera comprar el libro "Debugging Microsoft NET 2.0 Applications" de John Robbins. Aprendí mucho de este libro, incluido este truco.

+0

Esto supone que tiene código ejecutándose en el proceso, lo cual generalmente es una mala idea si desea monitorear todos los procesos. – MSalters

+0

@MSalters, cierto, pero en la práctica es una funcionalidad fácil de agregar a los ejecutables, y no requiere que sus clientes instalen ejecutables adicionales (o ejecuten procesos de supervisión por separado) – Patrick

Cuestiones relacionadas