2010-03-02 23 views
7

Tengo un cliente que está recibiendo un accidente reproducible 100% que no puedo reproducir en mi programa compilado en Visual Studio 2005. Los envié una versión de depuración de mi programa y mantuvo todos los archivos PDB y DLL a mano. Me enviaron el archivo de minivolcado, pero cuando lo abro me sale:Depuración de un minidump en Visual Studio, donde la pila de llamadas es nulo

"excepción no controlada en 0x00000000 en minidump.dmp: 0xc0000005: violación de acceso de lectura ubicación 0x00000000."

A continuación, la pila de llamadas muestra única "0x00000000()" y el desmontaje me muestra un volcado de la memoria en 0x0. Configuré el servidor de símbolos, cargué mis símbolos de PDB, etc. Pero no veo ninguna forma de saber cuál de las muchas DLL realmente causó el salto a nulo. Este es un proyecto grande con muchas dependencias, y algunas de ellas son binarias para las que no tengo el origen ni los PDB, ya que estoy usando una API como tercero.

Entonces, ¿cómo de qué sirve este minivolcado? ¿Cómo veo qué DLL causó el bloqueo? Nunca antes había usado minivolcados para la depuración, pero todos los tutoriales que he leído parecen mostrar al menos un nombre de función u otra cosa que le da una pista en la pila de llamadas. Acabo de obtener una línea que apunta a nulo.

También he intentado usar "Depende" para ver si había alguna dependencia DLL que no fue resuelto; sin embargo, en mis tres máquinas de prueba con varios SO de Windows, parece que obtengo tres conjuntos diferentes de dependencias DLL de SO (y aún no puedo replicar el bloqueo); así que esto no parece ser un método particularmente confiable para diagnosticar el problema.

¿Qué otros métodos están disponibles para determinar la causa de este problema? ¿Hay alguna manera de dar un paso atrás en una instrucción para ver qué DLL saltó a nulo?

+2

ld ModuleName cargará los símbolos de un módulo. ! analyze -v le dará un seguimiento de la pila. Entre esos dos, debe tener suficiente información para comenzar. http://windbg.info/doc/1-common-cmds.html tiene una lista de comandos WinDbg comunes. –

+0

Tienes razón Vanessa - Estaba usando el depurador integrado en Visual Studio, pero cuando uso WinDbg obtengo el nombre del módulo. ¿Está la lección aquí: no use el depurador de Visual Studio para corroer la pila de análisis post-mortem? – Piers

+0

Cada vez que he visto esto ha sido provocado llamando a un puntero de función nulo. – paulm

Respuesta

2

La idea detrás de todas formas 'simples' post mortem de la depuración es la captura de un seguimiento de la pila. Si su aplicación sobrescribe la pila, no hay forma de realizar dicho análisis. Solo métodos muy sofisticados, que graban toda la ejecución del programa en hardware dedicado, podrían ayudar.

El camino a seguir en tal caso son los archivos de registro. Extienda algunas declaraciones de registro muy amplia alrededor del área donde ocurre la falla y transmita esa versión al cliente. Después del bloqueo, verá la última declaración de registro en su archivo de registro. Agregue más instrucciones de registro entre ese punto y la siguiente declaración de registro que no se haya registrado en el archivo de registro, envíe esa versión nuevamente. Repita hasta encontrar la línea que causa el problema.

escribí un artículo de dos partes acerca de esto en ddj.com:

About Log Files Part 1

About Log Files Part 2

0

Sólo una observación, pero el la pila quedan truncados o, podría ser esta sobre-escrita un caso simple de usar un campo no inicializado, o quizás un desbordamiento de buffer?

Eso podría ser bastante fácil de localizar.

+0

Esperaría que el depurador de tiempo de ejecución lo captara si este fuera el caso. El hecho de que solo falla en aproximadamente el 10% de las computadoras me hace pensar que el problema está en otra parte. – Piers

0

¿Ha intentado ajustar WinDBG en el ordenador del cliente y usarlo como un depurador predeterminado para cualquier aplicación que causa un accidente? Solo necesita agregar archivos pdb a la carpeta donde reside su aplicación. Cuando ocurre un enamoramiento, se inicia WinDbg y puede intentar obtener la pila de llamadas.

0

Es posible que usted ya lo sabe, pero aquí hay algunos puntos sobre minidump depuración: 1 .Debe tener exactamente los mismos archivos ejecutables y PDB, como en la computadora cliente donde se creó el minivolcado, y deben colocarse exactamente en los mismos directorios. Solo reconstruir la misma versión no ayuda. 2. Debugger debe estar conectado al servidor de símbolos de MS. 3. Cuando se inicia el depurador, imprime el registro de carga del proceso en la ventana de Salida. En general, todas las bibliotecas deben cargarse correctamente con información de depuración. También se cargan las bibliotecas sin información de depuración, pero se imprime "sin información de depuración". Aprenda este registro, puede darle cierta información.

Si la pila ejecutable contiene marcos de una biblioteca sin información de depuración, es posible que no se muestre. Esto sucede, por ejemplo, si su código se ejecuta como devolución de llamada de la biblioteca de terceros.

Intente crear minivolcado en su propia computadora, agregando un código que crea una excepción no controlada y depúrela inmediatamente. ¿Esto funciona? Compare el registro de carga en sesiones de depuración exitosas y fallidas.

+0

Nota adicional: ¿cómo se crea un minivolcado en su código? Compare su código con este ejemplo: http://www.codeproject.com/KB/debug/postmortemdebug_standalone1.aspx –

+0

En realidad, la aplicación host con la que estoy trabajando está escribiendo el minivolcado, por lo que no tengo control directo sobre este proceso. . La mayoría de las veces funciona bien, pero no parece que se borre la pila de llamadas. – Piers

5

Bueno, parece que la respuesta en esta instancia fue "Usar WinDbg en lugar de Visual Studio para depurar minivolcados". No pude obtener ninguna información útil de VS, pero WinDbg me brindó una gran cantidad de información sobre la cadena de llamadas a funciones que condujeron al colapso.

En este caso, todavía no ayudó a resolver mi problema, ya que todas las funciones estaban en la biblioteca de terceros que estoy usando, por lo que parece que la única respuesta definitiva a mi problema específico es usar archivos de registro para rastrear el estado de mi aplicación que conduce al bloqueo.

Supongo que si alguien más ve un problema similar con una pila de llamadas inútil cuando depura un minivolcado, la mejor práctica es abrirlo con WinDgb en lugar de Visual Studio. Parece extraño que la mejor herramienta para el trabajo sea el producto gratuito de Microsoft, no el comercial.

La otra lección aquí es probablemente "cualquier programa que utiliza una biblioteca de terceros necesita para escribir un archivo de registro".

0

Puede haber llamado al puntero de función nulo. La información de la función de ejecución actual es necesaria para mostrar la información de la pila de llamadas. Forzar el puntero de la instrucción para iniciar cualquier función simple, luego verás la información de la pila de llamadas nuevamente.

void SimpleFunc() 
{ // <- set next statement here 
} 
Cuestiones relacionadas