tags:

views:

39

answers:

2

I have written a program that handles signal for Floating point exception and I am using Ubuntu 10.4.

Here's my source code :

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <setjmp.h>

sigjmp_buf mark;

void GeneralHandler(int signo)
{
    switch(signo)
    {

        case SIGFPE:
            printf("\nERROR : Invalid Arithmetic operation.\n");
            siglongjmp(mark, signo);
            break;
    }

    exit(signo);
}

int main(void)
{
    int i = 0,value = 0, ans = 0;
    struct sigaction act;
    act.sa_handler = GeneralHandler;

    sigaction(SIGFPE, &act, NULL);

    for(i = 0; i < 10; i++)
    {
        if(sigsetjmp(mark, 1)) continue;
        printf("Value : ");
        scanf("%d" ,&value);
        ans = 5 / value;
        printf("%d / %d = %d\n", 5, value, ans);
    }

}

I am using siglongjmp and sigsetjmp methods for jumping from the handler method to the main method inside for loop.

It works fine for the first time and displays ERROR : Invalid Arithmetic operation. and then displays Floating point exception for second time and then exits.

Program output :

searock@searock-desktop:~/C$ ./signal_continue
Value : 0
ERROR : Invalid Arithmetic operation.
Value :0
Floating point exception
searock@searock-desktop:~/C$

I am not sure what's wrong in my program? Why doesn't it show ERROR : Invalid Arithmetic operation. for the second time? Can someone point me in a right direction?

+3  A: 

You have not initialized your struct sigaction It's possible act contains garbage values, e.g. configuring the signal handler to SA_RESETHAND or something other bad.

Do struct

sigaction act = {};

or

memset(&act,0,sizeof act);
nos
Is memset() part of posix or stdlib ?
Searock
@Searock - memset() is basic Standard (ISO) C; header `<string.h>`.
Jonathan Leffler
Thanks for bearing with me. I am new to Posix.
Searock
Empty initializer lists like `{}` are fine in C++, but you have to use `{0}` instead in C, at least according to http://stackoverflow.com/questions/201101/how-to-initialize-an-array-in-c
bk1e
+2  A: 

I don't think you are supposed to logjump() out of a signal handler back into main code. The signal handler is supposed to just handle the signal and then return and let the main program execution go on in it's normal way.

I'm not sure what you are supposed to do about a SIGFPE, though. The man page for signal() says, not very promising:

According to POSIX, the behavior of a process is undefined after it ignores a SIGFPE, SIGILL, or SIGSEGV signal that was not generated by kill(2) or raise(3). Integer division by zero has undefined result. On some architectures it will generate a SIGFPE signal. [...] Ignoring this signal might lead to an endless loop.

sth
Please bear with me as I am a beginner. Is it harmful if I continue the program after the signal ?
Searock
@Searock: Generally signals are asynchronous events that are handled separately by the signal handler, the main program is not really directly affected by that. It should (automatically) continue to run as normal if the signal handler didn't kill it in response to the signal. But I'm no expert on this topic and don't know about how you are supposed to react to a FPE. (For division by zero there is of course the problem that the main program would still need to produce some result for that expression if it wants to continue executing.)
sth
Thanks for the explanation.
Searock