2008-09-22 12 views
6

A veces mi programa C++ se cuelga en modo de depuración, y lo que obtuve es un cuadro de mensaje que dice que una aserción falló en algunas de las rutinas de administración de memoria interna (accediendo a memoria no asignada, etc.). Pero no sé de dónde se llamó, porque no obtuve ningún rastro de pila. ¿Cómo obtengo un seguimiento de la pila o, al menos, veo dónde falla en mi código (en lugar de la biblioteca/rutinas incorporadas)?¿Cómo obtener un seguimiento de pila cuando falla el programa C++? (usando msvc8/2005)

Respuesta

7

Si tiene un bloqueo, puede obtener información sobre dónde ocurrió el bloqueo, ya sea que tenga una depuración o una versión de lanzamiento. Y puede ver la pila de llamadas incluso si está en una computadora que no tiene el código fuente.

Para hacer esto, necesita utilizar el archivo PDB que se creó con su EXE. Coloque el archivo PDB dentro del mismo directorio que el EXE que se colgó. Nota: incluso si tiene el mismo código fuente, crear dos veces y usar el primer EXE y el segundo PD no funcionará. Necesita usar el PDB exacto que se creó con su EXE.

A continuación, adjunte un depurador al proceso que se estrelló. Ejemplo: windbg o VS.

Luego, simplemente finalice la compra de su pila de llamadas, mientras que también tiene abierta la ventana de subprocesos. Deberá seleccionar el hilo que se colgó y verificar en la pila de llamadas para ese hilo. Cada hilo tiene una pila de llamadas diferente.

Si ya tiene adjuntado su depurador VS, irá automáticamente al código fuente que está causando el bloqueo por usted.

Si el bloqueo ocurre dentro de una biblioteca que está utilizando para el que no tiene el PDB. No hay nada que puedas hacer.

+0

Bueno, al menos se puede ver qué llamada de biblioteca provocó el bloqueo. – Thomas

+0

En la ventana intermedia de VS puede escribir (si tiene WinDBG): ".load sos.dll" (sin las comillas) y también usar el depurador SOS. – user7116

0

Si mal no recuerdo, ese cuadro de mensaje debería tener un botón que diga 'volver a intentar'. Esto debería romper el programa (en el depurador) en el punto donde ocurrió la afirmación.

3

Si ejecuta la versión de depuración en una máquina con VS, debería ofrecerla para que aparezca y le permita ver el seguimiento de la pila.

El problema es que el problema real ya no está en la pila de llamadas. Si libera un puntero dos veces, puede ocasionar este problema en otro lugar no relacionado con el programa (la próxima vez que algo acceda a las estructuras de datos del montón)

Escribí este blog sobre algunos consejos para mostrar el problema en la llamada Apila para que puedas descubrir qué está pasando.

http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx

El mejor consejo es utilizar la utilidad gflags para hacer cuestiones puntero causan problemas inmediatos.

+0

Gracias por la información sobre gflags que nunca supe sobre esto. –

+0

Tengo la sensación de que esta utilidad me ahorrará meses de trabajo en el futuro :) –

+0

Definitivamente, tan pronto como reciba algún tipo de bloqueo de memoria, solo uso la función de montón de página, ahorrando mucho tiempo. –

0

CrashFinder puede ayudarlo a localizar el lugar de la excepción dada la DLL y la dirección de la excepción reportada.
Puede tomar este código e integrarlo en su aplicación para generar automáticamente una acumulación de pila cuando hay una excepción no detectada. Esto generalmente se realiza usando __try{} __except{} o con una llamada al SetUnhandledExceptionFilter que le permite especificar una devolución de llamada a todas las excepciones no controladas.

2

Puede desencadenar un mini-volcado configurando un controlador para excepciones no detectadas.He aquí un article que explica todo sobre minivolcados

Google implementó en realidad su propio manejador de fallos de código abierto llamado BreakPad, que también el uso de Mozilla Creo que (eso es si quieres algo más serio - un rico y robusto manejador de fallos).

2

This article describe cómo calcular un seguimiento de pila.

0

También puede tener instalado un depurador post-mortem en el sistema del cliente. Esta es una forma decente y general para obtener información cuando no tiene una creación de volcado integrada en su aplicación (tal vez para una versión anterior para la cual todavía debe obtener información).

Dr. Watson en Windows se puede instalar ejecutando: drwtsn32 -i Al ejecutar drwtsn32 (sin ninguna opción) aparecerá el cuadro de diálogo de configuración. Esto permitirá la creación de archivos de volcado de bloqueo, que luego puede analizar con WinDbg o algo similar.

-1

Puede usar Poppy para esto. Simplemente rocíe algunas macros en su código y recogerá el seguimiento de la pila, junto con los valores reales de los parámetros, variables locales, contadores de bucles, etc. Es muy liviano por lo que puede dejarse en la compilación de lanzamiento para recopilar esta información de fallas en máquinas de usuario final

Cuestiones relacionadas