Bhavith C Acharya
Bhavith C Acharya

Reputation: 355

Inform parent process about child get signal after signal handler in child process is served

Hi currently I am collecting backtrace of child process in signal handler of child process . Then planning to send collected backtrace to parent process using message queue . My problem is when child process get any signal. child signal handler runs but informs parent process that child exited normally instead of child get signal. below is my code

void childProcess()
{
    int h =0 ;
    for(h=0;h<10;h++)
    {
        printf("child for loop running %d\n",h);
        //sleep(1);
        int q = 1/0; // generate floating point exception
    }

    exit(0);
}



void signalhandler(int signum, siginfo_t *si, void *arg)
{
    printf("signal received %s\n",strsignal(signum));
    printf("%d\n",signum);
    void *array[100];
    int size = 100;
    int addrLen = backtrace(&array,size);
    char ** sym = backtrace_symbols(&array,addrLen);
    int j = 0;
    printf("Test crashed due to %s\n",strsignal(signum));
    for(j=0;j<addrLen;j++)
    {
        printf("%u : %s\n",array[j],sym[j]);
    }
    raise(signum);             
    exit(signum);
}

void registerSignals()
{

    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sigemptyset(&sa.sa_mask);
    sa.sa_sigaction = signalhandler;
    sa.sa_flags = SA_SIGINFO;

    sigaction(SIGSEGV, &sa, NULL);       
    sigaction(SIGFPE, &sa, NULL);

}

int main()
{
    //while(1)
    {
        pid_t pid;
        pid = fork();
        if(pid == 0)
        {
            // child
            printf("child process id is %d\n",getpid());
            registerSignals();
            childProcess();
        }
        else
        {
            printf("parent process id is %d\n",getpid());
            // parent
            int iStatus;
            pid_t childPID = waitpid(pid,&iStatus,0);
            printf("iStatus is %d\n",WIFEXITED(iStatus));
            if(childPID == -1)
            {
                printf("wait pid failed\n");
            }
            else if(WIFEXITED(iStatus)==1)
            {
                printf("child exited normally!\n");
            }
            else if (WIFSIGNALED(iStatus)==1)
            {
                printf("child process terminated abnormally !!\n");
                int iSignalnumber = 0;
                // to fetch the signal number
                iSignalnumber = WTERMSIG(iStatus);
                printf("child process terminated due to %s\n",strsignal(iSignalnumber));
                // to check core file is generated or not
                if(WCOREDUMP(iStatus)==1)
                {
                    printf("core file is generated \n");
                }
                else
                {
                    printf("core file is not generated \n");
                }
            }
            int h ;
            for(h = 0; h<10;h++)
            {
                printf("parent executing : %d\n",h);
            }
        }
        printf("while loop executing with pid : %d \n", getpid());
        sleep(1);
    }

}

My requirement is after signal handler is served in child process the parent should print "child process terminated abnormally !!" but I am getting "child exited normally!" message

Upvotes: 1

Views: 999

Answers (1)

alk
alk

Reputation: 70883

From wait()'s Linux docs:

WIFEXITED(wstatus) returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().

The child signal handler ends the process using exit(), so everything works a specified.

Remove the call to exit() from the signal handler to get the expected result.


The call to raise() inside the signal handler most likely leads to recursive calls, so remove is as well.

Upvotes: 1

Related Questions