2011-01-07 11 views
42

Tengo un programa multiproceso C, que consistentemente genera un error de segmentación en un punto específico del programa. Cuando lo ejecuto con gdb, no se muestra ningún error. ¿Puede pensar en alguna razón por la cual la falla puede ocurrir solo cuando no se usa el depurador? ¡Es bastante molesto no poder usarlo para encontrar el problema!segfault solo cuando NO estoy usando depurador

+3

Este tipo de error se llama ["Heisenbug"] (http://en.wikipedia.org/wiki/Heisenbug#Heisenbug) y puede tener muchas causas. –

+0

¿El error está relacionado con la gestión de ventanas y/o User32.dll? – Mehrdad

+1

Tuve un problema como este, mi programa solo se bloqueó con GDB. El problema era que una variable miembro no clasificada aún obtenía el valor 0 cuando ejecuté mi programa, pero cuando lo ejecuté en GDB tenía un gran valor que segfaulted cuando lo usaba como un índice de matriz. – GWW

Respuesta

62

Classic Heisenbug. De Wikipedia:

El tiempo también puede ser un factor en heisenbugs. Ejecutar un programa bajo el control de un depurador puede cambiar el tiempo de ejecución del programa en comparación con la ejecución normal. Los errores sensibles al tiempo, como las condiciones de carrera, pueden no reproducirse cuando el programa se ralentiza mediante líneas fuente de paso único en el depurador. Esto es particularmente cierto cuando el comportamiento implica la interacción con una entidad que no está bajo el control de un depurador, como cuando se depura el procesamiento de paquetes de red entre dos máquinas y solo una está bajo el control del depurador.

El depurador puede estar cambiando el tiempo y ocultando una condición de carrera.

En Linux, GDB también deshabilita la aleatorización del espacio de direcciones, y su bloqueo puede ser específico para el diseño del espacio de direcciones. Pruebe (gdb) set disable-randomization off.

Finalmente, ulimit -c unlimited y la depuración post mortem (ya sugerido por Robie) pueden funcionar.

+8

'desactivó desactivar la aleatorización' resuelto un problema similar para mí! –

+0

¿Qué sucede si estoy usando LLDB? ¿Cuál es el comando equivalente? – thiagoh

+0

@thiagoh: Desafortunadamente no lo sé (no soy el que editó eso), es posible que quieras preguntarle a alguien más ... – Mehrdad

4

Al depurarlo, está cambiando el entorno en el que se está ejecutando. Parece que está tratando con algún tipo de condición de carrera, y al depurarlo las cosas se programan de forma ligeramente diferente para que no encuentre el problema. Eso o las cosas se almacenan de una manera ligeramente diferente para que no ocurra. ¿Puedes poner algo de depuración en el código para ayudar a resolver el problema? Eso puede tener un impacto menor y permitirle encontrar su problema.

5

Quizás cuando se utiliza gdb, la memoria se asigna en una ubicación en la que el flujo excesivo o descendente no afecta la memoria que causa un bloqueo. O podría ser una condición de carrera que ya no se dispare. Aunque suena poco intuitivo, debe ser feliz su programa fue lo suficientemente agradable como para chocar con usted.

Algunas sugerencias

  1. Pruebe con un analizador de código estático como el gratuito cppcheck
  2. Pruebe con un depurador malloc() como libefence
  3. Pruebe a ejecutar a través de valgrind
1

I ¡He tenido este problema por completo antes! Era una condición de carrera, y cuando estaba pisando el código con un depurador, el hilo en el que estaba era lo suficientemente lento como para no activar la condición de carrera. Bastante malo.

Cuestiones relacionadas