Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I handle and move past a segfault? [duplicate]

I'm working on a project in C involving linked lists, and I need to segfault a piece of code in order to prove it doesn't work. But my code can't crash.

Here's my handler so far:

typedef void sigfunc(int);
sigfunc *signal(int, sigfunc*);
void Handler(int sig)
{
    if (sig == SIGSEGV)
    printf("received SegFault\n");
    signal(SIGSEGV, &Handler);
}

It needs to survive the segfault. So far, all i get is an infinite loop of "recieved SegFault". Thanks in advance!

like image 783
user3357612 Avatar asked Feb 26 '14 20:02

user3357612


People also ask

How do you handle a segmentation fault?

Use debuggers to diagnose segfaults This simple trick will allow you to focus on that part of the code. If using backtrace on the core g file doesn't find the problem, you might have to run the program under debugger control, and then step through the code one function, or one source code line, at a time.

Is segfault an error?

Core Dump/Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you.” When a piece of code tries to do read and write operation in a read only location in memory or freed block of memory, it is known as core dump. It is an error indicating memory corruption.

Can segmentation fault be caught?

At the operating system level, this fault is caught and a signal is passed on to the offending process, activating the process's handler for that signal. Different operating systems have different signal names to indicate that a segmentation fault has occurred.


1 Answers

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.

like image 143
mah Avatar answered Sep 25 '22 14:09

mah