Su código está ignorando SIGSEGV en lugar de atraparlo. Recuerde que la instrucción que activó la señal se reinicia después de manejar la señal. En su caso, manejar la señal no cambió nada, así que la próxima vez que se intente la instrucción ofensiva, falla de la misma manera.
Si tiene la intención de captar la señal de este cambio
signal(SIGSEGV, SIG_IGN);
a este
signal(SIGSEGV, sighandler);
Debería probablemente utilizar en lugar de sigaction()
signal()
. Ver páginas man relevantes.
En su caso, la instrucción ofensiva es la que intenta desreferenciar el puntero NULL.
printf("%d", *p);
Lo que sigue depende completamente de su plataforma.
Puede usar gdb
para establecer qué instrucción de ensamblaje particular desencadena la señal.Si la plataforma es como la mía, se encuentra la instrucción es
movl (%rax), %esi
con registro rax valor 0 sosteniendo, es decir NULL
. Una forma (¡no portátil!) De solucionar esto en su manejador de señal es usar la tercera señal de argumento que obtiene su manejador, es decir, el contexto del usuario. Este es un ejemplo:
#include <signal.h>
#include <stdio.h>
#define __USE_GNU
#include <ucontext.h>
int *p = NULL;
int n = 100;
void sighandler(int signo, siginfo_t *si, ucontext_t* context)
{
printf("Handler executed for signal %d\n", signo);
context->uc_mcontext.gregs[REG_RAX] = &n;
}
int main(int argc,char ** argv)
{
signal(SIGSEGV, sighandler);
printf("%d\n", *p); // ... movl (%rax), %esi ...
return 0;
}
Este programa muestra:
Handler executed for signal 11
100
Es primero hace que el controlador para ser ejecutado por el intento de eliminar la referencia a Dirección NULL. A continuación, el controlador soluciona el problema configurando rax en la dirección de la variable n
. Una vez que el manejador retorna, el sistema reintenta la instrucción ofensiva y esta vez tiene éxito. printf()
recibe 100 como segundo argumento.
No recomiendo usar estas soluciones no portátiles en sus programas.
Habrá un tiempo en el que el código de escritura que traga segfaults será considerado suficiente para poner al programador en la cárcel. – 6502