Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Process behaviour after receiving a SIGSEGV signal?

Tags:

c

linux

unix

We recently learned about signals in UNIX our OS class. We use C to access the unix API.

A class mate was fooling around with dereferencing invalid pointers (to unallocated memory or null pointers) and then handling the resulting SIGSEGV signal. He had a code block that went something like this:

int* p;
int i = 0;
for (; i < 10; i++){
    printf("Iteration %d\n", i);
    p = i;
    int n = *p;
}

Then he had a simple signal handler that would simply print the signal number. What ended up happening was that the program would repeatedly print out that it had received a signal with the number 11 - a SIGSEGV signal and wouldn't ever exit the loop. Our professor found this behaviour to be odd and said he'd look into it.

From a search I did on the internet the behaviour does not seem to be at all odd, as the program is supposed to perform the offending instruction again after the signal it receives is handled in the case of a SIGSEGV. However this behaviour seems not to be documented anywhere in any of the official UNIX or LINUX documentation. Can any of you point me in the general direction of documentation regarding this type of behaviour?

EDIT:

The signal handler went something like this:

void signal_handler(int signo)
{
printf("%d\n", signo);
}

Redirecting console output to a file generated something like this:

Iteration 0
11
11
11
11
11
... (only stopped if we sent it a SIGINT)
like image 561
DeusImoral Avatar asked Nov 01 '22 07:11

DeusImoral


1 Answers

As the documentation you found says the response of the OS on returning from a SIGSEGV is undefined. Specifically for this instance it means that the relevant library standards don't define where it should resume but leave it to the exact details of the machine it's running on.

From memory X86 derived machines will restart the faulting instruction. However, Other processors skip that instruction an continue with the next. In general neither method is that useful as they both can create very weird behaviours.

As you might guess from this exactly what is done usually depends on the processor you're running on. For a particular processor the page fault response (and other faults) are all defined precisely this includes exactly what will happen if you do an 'Return' instruction on the fault stack frame.

In general, for a portable program, the only safe thing to do in a SIGSEGV handler is to exit the program. It is, however, possibly to use setjmp/longjmp if you're very, very careful about not trapping the signal during library calls or similar.

like image 166
user3710044 Avatar answered Nov 15 '22 07:11

user3710044