Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
05-30-2008, 03:23 PM
|
#1
|
LQ Newbie
Registered: Apr 2008
Posts: 16
Rep:
|
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?
|
|
|
05-30-2008, 06:59 PM
|
#2
|
Senior Member
Registered: May 2008
Location: planet earth
Distribution: Debian
Posts: 1,732
Rep:
|
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.
|
|
|
05-30-2008, 08:16 PM
|
#3
|
LQ Guru
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Rep:
|
|
|
|
05-30-2008, 08:23 PM
|
#4
|
HCL Maintainer
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450
Rep:
|
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: - kill by PID of the parent.
- When creating the child, use setpgid(), setsid() or some other measures to ensure that the child is no longer part of the same process group as the parent (and thus will not recieve a SIGINT on Ctrl-C).
|
|
|
06-02-2008, 09:07 AM
|
#5
|
LQ Newbie
Registered: Apr 2008
Posts: 16
Original Poster
Rep:
|
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().
|
|
|
06-02-2008, 03:45 PM
|
#6
|
LQ Newbie
Registered: Apr 2008
Posts: 16
Original Poster
Rep:
|
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?
|
|
|
06-02-2008, 04:10 PM
|
#7
|
HCL Maintainer
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450
Rep:
|
Quote:
Originally Posted by wkhoo
I can assume doing a exec() is the same as a fork()?
|
No, they are completely different. A call to fork() will create a two processes from one process. A call to one of the exec() functions will replace the current process image with that of a completely different process. Often, a call to exec() follows a call to fork() so you can call an arbitrary program without disrupting the currently-running one.
Quote:
Originally Posted by wkhoo
setpgid(), setsid() applies the same way as fork().
|
I don’t understand what you mean by this statement. setpgid() sets the PGID, and setsid() allows you to create a new session.
Quote:
Originally Posted by wkhoo
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.
|
Quote:
Originally Posted by wkhoo
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?
|
As you just said in the quote above this one, the child’s PGID is the same as the parent’s.
Quote:
Originally Posted by wkhoo
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.
|
When you Ctrl-C on the terminal, both parent and child receive the SIGINT signal. The child presumably does not have a SIGINT handler and terminates immediately, before the parent’s SIGINT handler gets a chance to send any messages.
Quote:
Originally Posted by wkhoo
What did I do wrong here? Is there any example that show me how to use the setpgid() correctly to elimiate this behaviour?
|
Consider the following program:
Code:
#include <stdio.h>
#include <unistd.h>
int main()
{
if(fork()) {
while(1) {
printf("Parent printing\n");
sleep(2);
}
} else {
#ifdef IMMUNE
setpgrp();
#endif
sleep(1);
while(1) {
printf("Child printing\n");
sleep(2);
}
}
return 0;
}
Compile the above program both with and without the flag ‘ -DIMMUNE’. First, run the non-immune one. When you are ready, press Ctrl-C at the terminal. As you notice, both processes are killed (this is because both receive SIGINT).
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.
|
|
|
06-03-2008, 01:13 PM
|
#8
|
LQ Newbie
Registered: Apr 2008
Posts: 16
Original Poster
Rep:
|
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?
Last edited by wkhoo; 06-04-2008 at 07:52 AM.
Reason: mod comments taken to account: code removed
|
|
|
06-03-2008, 05:21 PM
|
#9
|
HCL Maintainer
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450
Rep:
|
A few things which will help your problem get more attention: - Use [code] and [/code] tags to enclose sections of code and enhance readability.
- This is not a debugging service.
- If you are having a bug, reduce your code to the smallest sample of code which exhibits the problem. Post that small sample.
|
|
|
06-04-2008, 07:57 AM
|
#10
|
LQ Newbie
Registered: Apr 2008
Posts: 16
Original Poster
Rep:
|
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.
|
|
|
06-04-2008, 02:30 PM
|
#11
|
HCL Maintainer
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450
Rep:
|
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.
|
|
|
06-04-2008, 02:35 PM
|
#12
|
HCL Maintainer
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450
Rep:
|
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:
|
|
|
06-04-2008, 05:39 PM
|
#13
|
LQ Guru
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,398
|
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 05:45 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|