Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Killing the children with the parent

I have a program spawning and communicating with CPU heavy, unstable processes, not created by me. If my app crashes or is killed by SIGKILL, I want the subprocesses to get killed as well, so the user don´t have to track them down and kill them manually.

I know this topic has been covered before, but I have tried all methods described, and none of them seem to live up to survive the test.

I know it must be possible, since terminals do it all the time. If I run something in a terminal, and kill the terminal, the stuff always dies.

I have tried atexit, double fork and ptys. atexit doesn't work for sigkill; double fork doesn't work at all; and ptys I have found no way to work with using python.

Today, I found out about prctl(PR_SET_PDEATHSIG, SIGKILL), which should be a way for child processes to order a kill on themselves, when their parent dies. I tried to use it with popen, but it seams to have no effect at all:

import ctypes, subprocess
libc = ctypes.CDLL('/lib/libc.so.6')
PR_SET_PDEATHSIG = 1; TERM = 15
implant_bomb = lambda: libc.prctl(PR_SET_PDEATHSIG, TERM)
subprocess.Popen(['gnuchess'], preexec_fn=implant_bomb)

In the above, the child is created and the parent exits. Now you would expect gnuchess to receive a SIGKILL and die, but it doesn't. I can still find it in my process manager using 100% CPU.

Can anybody tell me if there is something wrong with my use of prctl?, or do you know how terminals manage to kill their children?

like image 407
Thomas Ahle Avatar asked Dec 10 '09 23:12

Thomas Ahle


People also ask

What do you call a parent who kills their child?

Filicide – the act of a parent killing their child (Latin: filius "son" and Latin: filia "daughter").

What is difference between filicide and infanticide?

Filicide is defined as the act of a parent killing her/his child. The killing of a child younger than one year is commonly called infanticide; when committed within the first 24 hours of life it is neonaticide.

What does filicide mean?

: the murder of one's own daughter or son.

How common is matricide?

Matricide, the killing of mothers by their biological children, is a very rare event, comprising less that 2% of all U.S. homicides in which the victim-offender relationship is known.


1 Answers

I know it's been years, but I found a simple (slightly hacky) solution to this problem. From your parent process, wrapping all your calls around a very simple C program that calls prctl() and then exec() solves this problem on Linux. I call it "yeshup":

#include <linux/prctl.h>
#include <signal.h>
#include <unistd.h>

int main(int argc, char **argv) {
     if(argc < 2)
          return 1;
     prctl(PR_SET_PDEATHSIG, SIGHUP, 0, 0, 0);
     return execvp(argv[1], &argv[1]);
}

When spawning your child processes from Python (or any other language), you can run "yeshup gnuchess [argments]." You'll find that, when the parent process is killed, all your child processes (should) be given SIGHUP nicely.

This works because Linux will honor the call to prctl (not clear it) even after execvp is called (which effectively "transforms" the yeshup process into a gnuchess process, or whatever command you specify there), unlike fork().

like image 160
coolbho3k Avatar answered Sep 21 '22 07:09

coolbho3k