Estoy tratando de depurar un simple recolector de basura stop-and-copy (escrito en C) usando GDB. El GC funciona mediante el manejo de SIGBUS. Establecí un punto de interrupción en la parte superior de mi controlador de señal SIGBUS. Le dije a GDB que pase SIGBUS a mi programa. Sin embargo, no parece funcionar.gdb: establezca un punto de interrupción para un manejador SIGBUS
el siguiente programa (que se explica en línea) muestra la esencia de mi problema:
#include <stdio.h>
#include <sys/mman.h>
#include <assert.h>
#include <signal.h>
#define HEAP_SIZE 4096
unsigned long int *heap;
void gc(int n) {
signal(SIGBUS, SIG_DFL); // just for debugging
printf("GC TIME\n");
}
int main() {
// Allocate twice the required heap size (two semi-spaces)
heap = mmap(NULL, HEAP_SIZE * 2, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED,
-1, 0);
assert (heap != MAP_FAILED);
// 2nd semi-space is unreadable. Using "bump-pointer allocation", a SIGBUS
// tells us we are out of space and need to GC.
void *guard = mmap(heap + HEAP_SIZE, HEAP_SIZE, PROT_NONE, MAP_ANON |
MAP_SHARED | MAP_FIXED, -1, 0);
assert (guard != MAP_FAILED);
signal(SIGBUS, gc);
heap[HEAP_SIZE] = 90; // pretend we are out of heap space
return 0;
}
me compilar y ejecutar el programa en Mac OS X 10.6 y obtener la salida espero:
$ gcc debug.c
$ ./a.out
GC TIME
Bus error
Quiero ejecutar y depurar este programa usando GDB. En particular, quiero establecer un punto de interrupción en la función gc (en realidad, el controlador de señal gc). Naturalmente, tengo que decirle BGF para no detener el SIGBUS así:
$ gdb ./a.out
GNU gdb 6.3.50-20050815 (Apple version gdb-1346) (Fri Sep 18 20:40:51 UTC 2009)
... snip ...
(gdb) handle SIGSEGV SIGBUS nostop noprint
Signal Stop Print Pass to program Description
SIGBUS No No Yes Bus error
SIGSEGV No No Yes Segmentation fault
(gdb) break gc
Breakpoint 1 at 0x100000d6f
Sin embargo, nunca alcanzamos el punto de interrupción:
(gdb) run
Starting program: /snip/a.out
Reading symbols for shared libraries +. done
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x0000000100029000
0x0000000100000e83 in main()
(gdb)
Al parecer, el manejador de la señal no se invoca (GC tiempo no es impreso). Además, todavía estamos en main(), en el mov de fallas:
0x0000000100000e83 <main+247>: movq $0x5a,(%rax)
¿Alguna idea?
Gracias.
Gracias, es un error específico de OS X. La solución hace que el programa se ejecute hasta su finalización, pero gdb ya no se detiene en el punto de interrupción. Oh, bueno ... –
Ver mi respuesta para una solución que le permite romper dentro del controlador. – LaC