crash - Se bloquea normalmente, pero no con GDB?
segmentation-fault (9)
Cuando ejecuta su código con gdb, se mueve. Ahora, la dirección ilegal a la que intentó hacer referencia anteriormente, la que provocó el segfault, es legal de repente. Es un dolor, seguro. Pero la mejor forma que conozco para rastrear este tipo de error es comenzar a poner printf () s por todos lados, reduciéndolo gradualmente.
Mi programa falla con una falla de segmentación cuando se ejecuta normalmente. Entonces lo ejecuto con gdb, pero no se bloqueará cuando lo haga. ¿Alguien sabe por qué esto podría ocurrir? Sé que las preguntas frecuentes de Valgrind mencionan esto (no se estrelló en valgrind), pero no pude encontrar nada sobre esto relacionado con gdb en google. Si alguien pudiera decirme por qué, o recomendar algo que buscar cuando esto ocurra, estaría muy agradecido.
Si el error depende del tiempo, el gdb podría evitar que se repita.
Suena como un Heisenbug que tienes ahí :-)
Si la plataforma con la que está trabajando es capaz de producir los archivos centrales, debería ser posible usar el archivo core y gdb para identificar la ubicación donde el programa se cuelga. Aquí puede encontrar una breve explicación.
Sin embargo, que se bloquee un par de veces, cuando la falla se debe a la destrucción de la pila o a la sobrescritura de la variable, el error puede parecer que "da la vuelta".
Ya me había pasado esto antes (no estás solo), pero no puedo recordar lo que hice para arreglar las cosas ( creo que fue una doble gratis).
Mi sugerencia sería configurar su entorno para crear volcados centrales, luego usar GDB para investigar el volcado del núcleo después de que el programa falle. En bash, esto se hace con ulimit -c size
, donde el tamaño puede ser cualquier cosa; Yo personalmente uso 50000 para un tamaño máximo de 25 MB; la unidad está en incrementos de 512 bytes.
Puede usar GDB para investigar un volcado del núcleo utilizando el gdb program core
.
Bueno, lo rastreé hasta una llamada pthread_detach. Estaba haciendo pthread_detach (& thethread). Me llevé la referencia y la cambié a pthread_detach (thethread) y funcionó bien. No estoy seguro, pero tal vez fue una doble gratis al separar la referencia y luego destruirla nuevamente cuando se salió de su alcance.
Intente adjuntar al proceso en ejecución dentro de gdb
, continuando y luego reproduciendo el bloqueo. En otras palabras, no inicie el programa dentro de gdb
; en su lugar, inicie el programa normalmente y luego attach <pid>
.
A veces, al pasar individualmente por las líneas, no se manifestará una condición de carrera que provoque que el programa se bloquee, ya que el peligro racial se ha eliminado o se ha vuelto extremadamente improbable por las pausas "prolongadas" entre los pasos.
También me sucedió esto algunas veces.
Mi solución: limpiar y reconstruir todo.
No digo que esto siempre solucione todos los problemas (y en el caso del OP el problema era realmente incorrecto), pero puedes ahorrarte un poco de tiempo si haces esto primero cuando te encuentres con errores "meta" tan extraños. Al menos, en mi experiencia, estas cosas a menudo provienen de viejos archivos de objetos que deberían haber sido reconstruidos pero que no lo eran. Tanto en MinGW como en GCC regular.
Compruebe el valor de retorno de la llamada pthread_detach
. Según su respuesta , probablemente esté pasando un identificador de subproceso no válido a pthread_detach
.
Acabo de tener un problema similar, en mi caso, estaba conectado a punteros en mi estructura de datos enlazados. Cuando creé dinámicamente una nueva lista sin inicializar todos los punteros dentro de la estructura, mi programa se bloquea fuera de GDB
Aquí están mis estructuras de datos originales:
typedef struct linked_list {
node *head;
node *tail;
} list;
typedef struct list_node {
char *string;
struct list_node *next;
} node;
Cuando creé una nueva "instancia" de una list
especificaba su head
y tail
el programa se bloqueó fuera de DGB
:
list *createList(void) {
list *newList = (list *) malloc(sizeof(list));
if (newList == NULL) return;
return newList;
}
Todo comenzó a funcionar normalmente después de que cambié mi función createList
a esto:
list *createList(void) {
list *newList = (list *) malloc(sizeof(list));
if (newList == NULL) return;
newList->head = (node *) 0;
newList->tail = (node *) 0;
return newList;
}
Espero que pueda ayudar a alguien en caso de algo similar a mi ejemplo con punteros no inicializados.