c++ - ¿Cómo puedo depurar un proceso win32 que inesperadamente termina en silencio?
debugging winapi (11)
En primer lugar, quiero decir que solo tengo una experiencia moderada en el desarrollo de Windows. Después de eso, creo que este es un caso típico en el que un registro puede ayudar.
Normalmente, la depuración y el registro proporcionan información ortogonal. Si su depurador es inútil probablemente el registro lo ayude.
Tengo una aplicación de Windows escrita en C ++ que ocasionalmente se evapora. Utilizo la palabra evaporar porque no queda nada atrás: ningún mensaje de "lo lamentamos" de Windows, ningún volcado de la instalación del Dr. Watson ...
En una ocasión, el bloqueo se produjo bajo el depurador, el depurador no se rompió, mostró que la aplicación aún se estaba ejecutando. Cuando detuve manualmente la ejecución, descubrí que mi proceso ya no tenía subprocesos.
¿Cómo puedo capturar la razón por la cual este proceso está terminando?
Esto podría ser una llamada a _exit () o algún equivalente de Windows. Intenta establecer un punto de interrupción en _exit ...
La causa más común para este tipo de desaparición repentina es un desbordamiento de pila, generalmente causado por algún tipo de recursión infinita (que puede, por supuesto, involucrar una cadena de varias funciones que se llaman entre sí).
¿Es eso una posibilidad en tu aplicación?
Podría intentar usar la utilidad adplus en el paquete de herramientas de depuración de Windows .
adplus -crash -p yourprocessid
La herramienta de volcado automático proporciona mini volcados para excepciones y un volcado completo si la aplicación falla.
Puede verificar los registros de Windows en el Visor de eventos en Windows.
Si está utilizando Visual Studio 2003 o posterior, debe habilitar la función de controlador "Excepción de primera oportunidad" de los depuradores activando TODAS las opciones de excepción de depuración encontradas en el menú Depurar | Diálogo de excepciones. Active TODAS las opciones antes de iniciar la compilación de depuración del proceso dentro del depurador.
De forma predeterminada, la mayoría de estos manejadores de excepción de First Chance en el depurador están desactivados, por lo que si Windows o su código arrojan una excepción, el depurador espera que su aplicación lo maneje.
El sistema de excepción de primera oportunidad permite a los depuradores interceptar CADA posible excepción lanzada por el proceso y / o sistema.
¿Has probado PC Lint, etc. y ejecutarlo sobre su código? Intente compilar con advertencias máximas. Si se trata de una aplicación .NET, use FX Cop.
Las posibles causas vienen a la mente.
- TerminateProcess ()
- Excepción de desbordamiento de pila
- Excepción al manejar una excepción
El último en particular da como resultado una falla inmediata de la aplicación.
El desbordamiento de la pila: es posible que reciba una notificación al respecto, pero es poco probable.
Súmese al depurador, cambie todas las notificaciones de excepción a "detener siempre" en lugar de "detener si no se maneja", luego haga lo que hace para causar la falla del programa. El depurador se detendrá si obtiene una excepción y puede decidir si esta es la excepción que está buscando.
Bueno, el problema es que está recibiendo una violación de acceso. Es posible que desee adjuntar con WinDBG y activar todos los filtros de excepción. Puede que aún no ayude, supongo que está sufriendo corrupción en la memoria que no arroja una excepción.
Es posible que desee consultar la habilitación de la comprobación completa del mapa de página
Es posible que también desee consultar esta pregunta anterior sobre la corrupción del montón para obtener algunas ideas sobre herramientas.
Todas las otras ideas publicadas son buenas.
Pero también parece que la aplicación llama a abort () o terminate ().
Si lo ejecuta en el depurador, establezca un punto de interrupción en ambos métodos y exit () solo por si acaso.
Aquí hay una lista de situaciones que provocarán que se llame a terminación debido a excepciones que salen mal.
Ver también: ¿Por qué no se llama a destructor en la excepción?
Esto muestra que una aplicación terminará () si no se detecta una excepción. Así que pegue un bloque catch en main () que informa el error (a un archivo de registro) y luego vuelva a lanzar.
int main()
{
try
{
// Do your code here.
}
catch(...)
{
// Log Error;
throw; // re-throw the error for the de-bugger.
}
}
Pasé un par de horas intentando profundizar en esto en Visual Studio 2017 con una aplicación de 64 bits en Windows 7. Terminé por tener que establecer un punto de interrupción en la función RtlReportSilentProcessExit , que vive en el archivo ntdll.dll . Solo el nombre de la función base fue suficiente para que Visual Studio lo encuentre.
Dicho esto, después de dejar que Visual Studio descargue símbolos automáticamente para la biblioteca estándar de C, también se detuvo automáticamente en la excepción de tiempo de ejecución que causó el problema.