Categories
Code

crash handling

Estaba yo preguntándome esta tarde si sería posible lanzar de forma automática gdb cuando un programa cascara, sin necesidad de ponerse a depurar después, reproducir el bug, etc, al estilo del manejador de errores que instala Visual Studio en Windows que pregunta si se desea depurar la aplicación.

Me ha salido algo como esto (HTML horrible para el coloreado de sintaxis patrocinado por Vim):

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

void attach_gdb(int signum)
{
    pid_t gdbpid;
    pid_t debuggee_pid = getpid();
    int gdb_exit_status;
    char pidbuf[100];
    char exebuf[100]; // should be safe unless PIDs reach ~90 digits ;P
    sprintf(pidbuf, "%d", debuggee_pid);
    sprintf(exebuf, "/proc/%d/exe", debuggee_pid);
    printf("Signal %d received. Attaching GDB to process. PID=%d\n", signum, debuggee_pid);

    if ((gdbpid = fork()) == 0)
    {
        execlp("gdb", "gdb", exebuf, pidbuf, NULL);
        perror("execlp");
        exit(1);
    }

    waitpid(gdbpid, &gdb_exit_status, 0); // hold on, we want to be debugged
    exit(1);
}

void __attribute__((constructor)) setup_handler()
{
    struct sigaction sa, old_sa;
    sa.sa_handler = attach_gdb;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags=0;
    // Register the handler for all actions which dump core by default
    sigaction(SIGSEGV, &sa, &old_sa);
    sigaction(SIGFPE, &sa, &old_sa);
    sigaction(SIGABRT, &sa, &old_sa);
    sigaction(SIGILL, &sa, &old_sa);
    sigaction(SIGQUIT, &sa, &old_sa);
}

Si se compila como librería dinámica y se enlaza a cualquiera de nuestros programas (o se precarga con LD_PRELOAD) lanza un gdb asociado al proceso al recibir cualquiera de las señales que causarían un core dump y terminación del programa :D.

¿Alguna idea para mejorarlo y que sea práctico? ¿Existe ya algo asi en un paquete Debian que hace mil cosas molonas más? (seguro que sí XD).

One reply on “crash handling”

Comments are closed.