Generally speaking, once you've hit a SEGFAULT your process is done.
In specialized terms, it might be possible to recover, but doing so without being acutely aware of what you're doing is a recipe for repeated failures, memory leaks, invalid pointers, and a nightmare of other problems.
That being said, unless you can restart your process (which avoids all of the above), you can try to recover using setjmp()
and longjmp()
. For example:
#include <setjmp.h>
jmp_buf restore_point;
void Handler(int sig)
{
if (sig == SIGSEGV)
{
printf("received SegFault\n");
signal(SIGSEGV, &Handler);
longjmp(restore_point, SIGSEGV);
}
}
void test()
{
int fault_code = setjmp(restore_point);
if (fault_code == 0)
{
// do something that might cause a segfault
}
else
{
printf("recovered from a fault; code = %d\n", fault_code);
}
}
In addition to the other problems I've listed, another is that the restore point (jump buffer) you set is only valid until the scope that calls setjmp()
is terminated.... you must not jump back into a terminated scope!
In essence, longjmp()
is a far-reaching goto
, but more like a gobackto
since it goes back to the point the jump buffer was initialized. It got initialized by the setjmp()
function in a manner than ensures setjmp()
will return 0 when it's called linearly, and it will return non-zero when it's reached by being longjmp'd into. In that case, it returns whatever longjmp()
s second parameter is (unless that parameter == 0, in which case it returns non-zero still).
Seriously, I've given you enough information to make you dangerous, but don't take my cautions lightly... it's far easier to compound your problems with this approach than it is to fix them, unless you've taken great care and limited your use of this tool.
printf()
in a signal handler is not safe. #8493595 – Eogene