LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
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

Reply
 
Search this Thread
Old 05-30-2008, 03:23 PM   #1
wkhoo
LQ Newbie
 
Registered: Apr 2008
Posts: 16

Rep: Reputation: 0
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?
 
Old 05-30-2008, 06:59 PM   #2
pinniped
Senior Member
 
Registered: May 2008
Location: planet earth
Distribution: Debian
Posts: 1,732

Rep: Reputation: 50
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.
 
Old 05-30-2008, 08:16 PM   #3
paulsm4
Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
You might want to look at setsid () and friends:

http://www.enderunix.org/documents/eng/daemon.php
http://linux.die.net/man/2/setsid
 
Old 05-30-2008, 08:23 PM   #4
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
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).
 
Old 06-02-2008, 09:07 AM   #5
wkhoo
LQ Newbie
 
Registered: Apr 2008
Posts: 16

Original Poster
Rep: Reputation: 0
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().
 
Old 06-02-2008, 03:45 PM   #6
wkhoo
LQ Newbie
 
Registered: Apr 2008
Posts: 16

Original Poster
Rep: Reputation: 0
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?
 
Old 06-02-2008, 04:10 PM   #7
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
Quote:
Originally Posted by wkhoo View Post
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 View Post
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 View Post
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 View Post
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 View Post
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 View Post
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.
 
Old 06-03-2008, 01:13 PM   #8
wkhoo
LQ Newbie
 
Registered: Apr 2008
Posts: 16

Original Poster
Rep: Reputation: 0
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
 
Old 06-03-2008, 05:21 PM   #9
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
A few things which will help your problem get more attention:
  1. Use [code] and [/code] tags to enclose sections of code and enhance readability.
  2. This is not a debugging service.
  3. If you are having a bug, reduce your code to the smallest sample of code which exhibits the problem. Post that small sample.
 
Old 06-04-2008, 07:57 AM   #10
wkhoo
LQ Newbie
 
Registered: Apr 2008
Posts: 16

Original Poster
Rep: Reputation: 0
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.
 
Old 06-04-2008, 02:30 PM   #11
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
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.
 
Old 06-04-2008, 02:35 PM   #12
osor
HCL Maintainer
 
Registered: Jan 2006
Distribution: (H)LFS, Gentoo
Posts: 2,450

Rep: Reputation: 70
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
 
Old 06-04-2008, 05:39 PM   #13
chrism01
Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.5, Centos 5.10
Posts: 16,269

Rep: Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028Reputation: 2028
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'.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how parent process can control it's child? sluge Linux - General 2 08-02-2007 04:31 AM
child process usses same amount of ram as parent process socialjazz Programming 7 10-19-2006 05:48 PM
Bash Scripting - child process affecting parent process mthaddon Linux - General 1 05-02-2004 01:19 PM
about parent and child process winwar Solaris / OpenSolaris 3 07-23-2003 06:07 AM
child and parent process error jdevanand Programming 1 04-29-2002 08:13 AM


All times are GMT -5. The time now is 01:42 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration