Archivo de 7 de mayo de 2009

Backtraces en C

Jueves, 7 de mayo de 2009 por

El otro día me entró la curiosidad de cómo podía saber al ejecutar un programa donde se producía un segmentation fault, por ejemplo, que es bastante común en mi caso :-) con ayuda de algún compañero de trabajo encontramos la página de GNU en la que se refieren a los Backtraces.

Para usarlo, hay que poner un #include <execinfo.h> y las opciones -g y -rdynamic, si utilizas el compilador y el linker de GNU. De esta manera se guardan en el ejecutable todos los símbolos. Aumenta el tamaño de los ejecutables, con lo que conviene sólo usarlo mientras se hacen pruebas. Esta librería tiene tres funciones:

  • int backtrace (void **buffer, int size): Rellena buffer con los size punteros obtenidos del backtrace del thread en ejecución. Devuelve el número de punteros devueltos, menor o igual que size.
  • char ** backtrace_symbols (void *const *buffer, int size): Rellena buffer con los nombres (símbolos) del backtrace, hasta un máximo de size.
  • void backtrace_symbols_fd (void *const *buffer, int size, int fd): Hace la misma operación que la anterior, pero devolviendo los strings al fichero fd, en lugar de al buffer de punteros.

Ejemplo de función de uso (de la página de GNU):

     print_trace (void)
     {
         void *array[10];
         size_t size;
         char **strings;
         size_t i;

         size = backtrace (array, 10);
         strings = backtrace_symbols (array, size);

         printf ("Obtained %zd stack frames.\n", size);

         for (i = 0; i < size; i++)
            printf ("%s\n", strings[i]);

         free (strings);
     }

Estas funciones sólo obtienen los datos correspondientes al thread que llama a estas funciones. Si por ejemplo quieres ver las funciones que se llaman en un segmentation fault, deberías cazar la señal SIGSEGV con la función signal de signal.h y llamar a una función que llame a las de execinfo.h.

Enlace: Backtraces, GNU library