Solved

signal handler for SIGCHLD gets called twice if parent process also gets killed

Posted on 2003-10-23
17
1,026 Views
Last Modified: 2013-12-26
Hi,

I have a parent process that forks a child process and from there execlp another executable. The parent process and the exe uses pipes for IPC. The parent process has a signal handler that handles the SIGCHLD signal as follows :

    struct sigaction act;

    act.sa_handler = SIG_IGN;
    sigemptyset(&act.sa_mask);
    act.sa_flags   = 0;
    sigaction(SIGPIPE, &act, 0);

    act.sa_handler = child_killed; //handler function
    act.sa_flags  = SA_NOCLDSTOP | SA_NODEFER;
    sigemptyset(&act.sa_mask);

    if(sigaction(SIGCHLD,&act,0)) {
        exit(1);
    }

In the child_killed(), I close the read end of the pipe.
Some times just after the child process exits, the parent process goes 100% (at times I see that the signal handler gets called in logs and some times i do not see the logs, so i cannot be sure that everytime the problem happens the signal handler gets called in parent). Also the child process becomes a Zombie. After I kill and restart the Parent process I see in its logs that the signal handler is called again but this time with child pid as -1.  

Can you please tell me why the signal handler is getting called in the newly started parent process.

Also I would like to know that whether there is a chance that even after the child exits the signal handler doesn't gets called in the parent.

Thanks,
Avinash
0
Comment
Question by:avidamani
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 5
  • 2
  • +2
17 Comments
 
LVL 45

Expert Comment

by:sunnycoder
ID: 9612761
>Can you please tell me why the signal handler is getting called in the newly started parent process.
cannot be unless there is a bug in the library ... run your program through a debugger

>whether there is a chance that even after the child exits the signal handler doesn't gets called in the parent.
yes, if you are executing child_killed() when a child exits, signal will not be delivered ... this is the default behaviour... when you are handling a signal and same signal arrives, it is not delivered ... also if more than one children exit simultaneously, your application will see only one signal
you might like to look into sigpending()
0
 

Author Comment

by:avidamani
ID: 9613950
Hi sunnycoder,

Thanks for the reply. Can you elaborate which library are you talking about.

Also there is only one child process, so there is no chance of getting another sigchild. THe problem is that the parent process goes upto 100% CPU utilization around the time the child exits. There is no way to confirm whether the parent went 100% before the sigchld came or after that. Also the problem is happening rarely and so there is no way to reproduce it with the code as it is.
1 more thing, is it possible to miss a signal if theparent process is very busy processing something else.
Cause i know for sure that if i do not close the reading end of the pipe after the child exits, parent process will shoot upto 100% quickly, but whats baffling me is that why the sigchld handler is not getting called.

Thanks,
Avinash

0
 

Author Comment

by:avidamani
ID: 9614298
Also to add, The parent and child process are communicating through pipe, where Child is the writer and parent reads from the pipe using the following :

       XtAddInput(fd, (char *)xmask, callback, ptr));

Now if the child exits/gets killed, what will the status of the pipe at parent, will the callback keep on getting called? SIGPIPE signal comes when you write to a pipe which has no reader. right? Is there anything that tells that the pipe is empty from which you are reading, i.e. there is no writer to it.

Thanks,
Avinash
0
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 
LVL 1

Expert Comment

by:fsign21
ID: 9628269
Could you please post a bit more of you code
1) where do you call pipe() and fork()
2) more important, where and how do you call wait() or waitpid(). Since, you are getting zombies, I assume, it is something wrong with waiting.
If the parent doesn't wait, but exits before the child process does, then the child is adopted by another process (usually the one with PID 1). After the child exits (but before it's waited for) it becomes a "zombie". If it's never waited for (because the parent process is hung, for example) it remains a zombie.

I post just a small example for fork() and pipe()
http://www-h.eng.cam.ac.uk/help/tpl/unix/fork.html
0
 

Author Comment

by:avidamani
ID: 9629723
1)The fork code :  
   ============
 if ((pid = fork()) < 0)
    {
        if (pipe_ok) {
            close(fd[0]);
            close(fd[1]);
        }
        return;
    }
    else
    {
        if (pid == 0)
        {
            // Close the read half of the pipe.
            if (pipe_ok)
                close(fd[0]);

            // I AM THE CHILD - transform into another process
            if (execlp(a_exec,
                       a_exec,
                       (char *)NULL) < 0)
            {
                 exit(2);
            }
        }



2) I am calling wait() in the signal handler. So the child will remain Zombie till its signal handler is called.
   
     c_pid = wait(&c_status);

    I understand the zombie concept but since I'm calling wait in the signal handler, and signal is the highest
    priority stuff in unix, even though parent is hung/busy, the signal handler should get called.
   
    Also I'm not sure why the signal handler is called again after I've kill/restarted the parent process, even though there was only 1 child that was killed and was in zombie state. Since init will adopt the zombie and clean it up as it is now an orphan.

Thanks
0
 
LVL 1

Expert Comment

by:fsign21
ID: 9633264
The code for // I AM THE PARENT ?

I guess, you have a big project with GUI and it is difficult to post all you source...
If you want, you can send me the code to fsign21@gmx.net and I can have a look on it.
0
 

Author Comment

by:avidamani
ID: 9635631
I cannot post the source code as its a proprierty thing. But yaa its a bif project :)
0
 

Author Comment

by:avidamani
ID: 9644128
I was wondering what made the signal handler to get called after the parent process was killed. In this case, the init will take over the child and clean it up as child exited before parent was killed.
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 9670591
sorry for late reply.. I was away on a vacation ... were you able to solve the problem or is it still open?
0
 

Author Comment

by:avidamani
ID: 9671010
The problem is still there..... :(
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 9679632
>1 more thing, is it possible to miss a signal if theparent process is very busy processing something else
no

>Cause i know for sure that if i do not close the reading end of the pipe after the child exits
as far as I remember, you should be closing the read end first

>SIGPIPE signal comes when you write to a pipe which has no reader. right?
right

>Is there anything that tells that the pipe is empty from which you are reading, i.e. there is no writer to it.
No signal but reads will return nothing... that is sufficient diagostic that no data is available

>and signal is the highest priority stuff in unix,
some interrupts have higher priority

>why the signal handler is called again after I've kill/restarted the parent process
this is strange and I am surprised too... add some code to signal handler and in that signal handler print the ID of the process which sent the signal... to get this id print the si_pid member of siginfo_t .. also try running the code through a debugger

>init will adopt the zombie and clean it up as it is now an orphan.
no, it wont clean it up
0
 

Author Comment

by:avidamani
ID: 9701956
The signal handler is getting called in the next process with pid of -1
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 9706168
is it a daemon process? are you using setsid() or fork to make it process group leader ?
0
 

Author Comment

by:avidamani
ID: 9734745
Yes it is... It gets restarted as soon as it gets killed from inittab.
I'll try to explain the scenario again.

1) client makes a call.
2) This process forks off a child.
3) The child exits and becomes a zombie.
4) The parent at times hits the signal handler .. at times dont
5) I kill the parent after some time (once after 1 day)
6) The new process gets respawned from inittab entry
7) Its signal handler gets hit and the child pid is shown as -1 when i do a wait in the signal handler.

I want to know why the signal handler of the new process gets hit. It didn't do a fork() or setsid(). Fork() was done by the previous process which I killed.
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 9753437
2) This process forks off a child.
3) The child exits and becomes a zombie.
4) The parent at times hits the signal handler .. at times dont

I am sure you are missing out on something in your code ... Check it again or still better ask someone else to do it for you .... IPC mechanism is a time-tested mechanism which has stood for decades now ... This is an issue with your code.

>7) Its signal handler gets hit and the child pid is shown as -1 when i do a wait in the signal handler.
how do you get the child pid ? pid of -1 is invalid for a sending process... However, it is possible to send a signal to pid -1. This would send a signal to all the processes in the group except the first one
0
 
LVL 18

Expert Comment

by:liddler
ID: 10191592
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

PAQ  No refund

Please leave any comments here within the next seven days.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

liddler
EE Cleanup Volunteer
0
 

Accepted Solution

by:
modulo earned 0 total points
ID: 10241705
PAQed - no points refunded (of 230)

modulo
Community Support Moderator
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …
Suggested Courses

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question