memory leak: Parent killing child process
How can I cleanly terminate Child Process without memory leak on a Ctrl-C?
Parent program monitor SIGINT signal, Child program monitor on a SIGTERM. I start the child program with exec. on a Ctrl-C the process handler sends a kill(child's pid, SIGTERM), to the child process. what I am observe is the child process does not handle this signal and terminates. what I noticed is when the parent program terminate, it will terminate the child program too. Does it automatically sends a SIGKILL to the child process? how does it work? |
See the man pages for 'prctl'.
According to the documentation of 'fork()', the child should not be killed when the parent terminates (it becomes an 'orphan' and will be adopted by another process - 'init' if no one else wants it). You can use 'prctl' to check that the settings are as expected. |
You might want to look at setsid () and friends:
http://www.enderunix.org/documents/eng/daemon.php http://linux.die.net/man/2/setsid |
Indeed a parent can die and leave children behind, in which case they will be inherited by a process higher up in the hierarchy (one which is wait()ing for children or has a suitable handler for the SIGCHLD signal).
When you have a process created on a terminal it is in the session of the shell which created it (so its SID will match that of the shell). The shell will give it a PGID matching its PID and make that PGID the foreground process of the terminal. If the process fork()s both the parent and child will retain the PGID. So when you type Ctrl-C at the terminal, a SIGINT is generated and sent to all processes in the foreground process group (i.e., all processes whose PGID matches the PID of command started by the shell). This is why a Ctrl-C will kill both child and parent. If you want to kill the parent without killing the child, you can do one of a few things:
|
Thank for the tip, will read into the man pages and try it out.
I can assume doing a exec() is the same as a fork()? and setpgid(), setsid() applies the same way as fork(). |
I forget to mention I am running valgrind on the child process.
in the parent I called the below to track memory leaks in the child process. execlp("libtool", "", "--mode=execute", "valgrind --tool=memcheck --leak-check=full", program_name, sock_addr, user_args, NULL); using getpid and getpgrp in the parent program the PID and GPID are the same. The child has a unique PID whereas the GPID is same with the Parent's GPID. using ps -ef UID PID PPID C STIME TTY TIME CMD wkhoo 2350 5750 0 15:08 pts/8 00:00:00 ./puiface wkhoo 2353 2350 19 15:08 ? 00:00:07 /usr/bin/valgrind.bin --tool=memcheck --leak-check=full ./gen_router /tmp/puiface14_1 p wkhoo 2386 1591 0 15:09 pts/3 00:00:00 ps -ef From my limited understanding shouldn't the parent terminates and leave behind a zombie process as the GPID of the parent and child are different? On a Ctrl-C in the terminal, the parent receives the SIGINT signal and calls its terminate handler routine to clean up. The parent sent a socket msg to the child asking it to clean up. The child process receives the msgs and before it can execute the clean up route it terminates abruptly. causing memory leaks in pthread_create. What did I do wrong here? Is there any example that show me how to use the setpgid() correctly to elimiate this behaviour? |
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Code:
#include <stdio.h> Now, run the immune one. This time, when you press Ctrl-C at the terminal, only the parent receives the SIGINT, and the child lives on. |
I am grateful for your detail explaination and example.
I am able to start my child process with setpgrp() on a different GPID. Termination of the parent now will not terminate the child. My goal of cleaning up the child is still unfulfilled. on a SIGINT, the parent sends a message to the child to clean up itself. The code below is whats in my child program, when it gets the message it calls the pthread_cancel to close the thread. The issue when the call to pthread_cancel is called the program just hangs there. There is no return on pthread_cancel. By me introducing setpgrp in the parent did I just changed how thread is close in the child process? What is the hidden effects of changing GroupId and Threads? |
A few things which will help your problem get more attention:
|
Thank you mod, I understand fully its not a debugging service.
Not expecting that. wasn't think thru, thought that with code will help ppl understand the problem. I have taken your advice and remove the code, as it was not my intend. tried googling with different keys like "pthread_cancel Hang and setpgrp" but did not yield good results. Wanted to know what could have gone wrong by changing setgprg on threads. as when I remove the code, thru a different use case the child process is able to perform pthread_cancel without problems. |
First, I am not a mod. Second, my advice was not for you to remove the code, my advice was for you to produce the smallest portion of code which demonstrates the problem, so we may more easily asses a solution.
|
Btw, as I said in my first post, you can completely avoid the issue by not using Ctrl-C at all.
If you do not wish to use setpgrp() or setsid(), you may instead just issue a manual kill on the parent process: Code:
kill -SIGINT pid |
Can I just clarify if you are using fork() or threading? As a general rule, you shouldn't mix the two in the same 'program'.
|
All times are GMT -5. The time now is 07:01 AM. |