9

Problem

I would like to kill a process called raspivid (program which records videos using a Raspberry Pi Camera) but I cannot...

This is how I call it:

#!/bin/bash

#Start recording...
raspivid -w 800 -h 600 -t 15000 -o $1 -v -n -rot 270 >> /home/pi/log/camera_output.txt 2>&1 &

#Waiting the video to be complete
sleep 16

#Killing child process
sudo kill -9 $!

#Killing parent process
sudo kill -9 $$

If I search for this process, it is still there:

pi@raspberrypi ~ $ ps -ef | grep raspivid
root      7238     7234  0 21:53 ?        00:00:00 [raspivid]
pi       17096 14925  0 22:05 pts/0    00:00:00 grep --color=auto raspivid

If I try to kill it, it doesn't die. Instead it changes the parent PID to 1:

pi@raspberrypi ~ $ sudo killall raspivid
pi@raspberrypi ~ $ ps -ef | grep raspivid
root      7238     1  0 21:53 ?        00:00:00 [raspivid]
pi       17196 14925  0 22:05 pts/0    00:00:00 grep --color=auto raspivid
pi@raspberrypi ~ $ sudo killall raspivid

Observations:

  1. The call works fine for a while (2 hours or something) then it starts hanging.
  2. Only a physical power off solves the issue. I cannot reboot via terminal (it hangs too)

My questions:

  1. Why does Linux assign the parent PID to 1?
  2. Why the process cannot get killed? (I also tried sudo kill -9 7238)

4 Answers 4

2

Problem

Your script is probably creating zombies because of your kill -9 commands; as suggested from jjlin answer too is never a good practice to kill abruptly some process without being forced to.

From man bash we can read:

Processes marked < defunct > are dead processes (so-called "zombies") that remain because their parent has not destroyed them properly. These processes will be destroyed by init(8) if the parent process exits.

Answer #1: The process init has the PID 1 and for this Linux assigns them the parent with PID 1 (because it assign them to init).

Answer #2: They cannot be killed simply because they are just dead... if their parent is init probably is enough to wait some time.

To remove zombies from a system, the SIGCHLD signal can be sent to the parent manually, using the kill command. If the parent process still refuses to reap the zombie, the next step would be to remove the parent process. When a process loses its parent, init becomes its new parent. Init periodically executes the wait system call to reap any zombies with init as parent. [1]

Just in case this idea arises one day or another: to #kill -9 init process with root privilege is the software equivalent to physically unplug the computer from the electricity grid. [:-)]

However zombie processes can be identified in the output of ps command by the presence of a "Z" in the STAT column. You can use the following line to easily identify them

ps -aux | grep Z

Some references about Linux zombies world:

5
  • A process with parent PID 1 is not a zombie. A process gets this parent when its parent is killed before it is. So his killall is apparently killing the parent, not the process he wanted to.
    – Barmar
    Feb 6, 2015 at 19:41
  • Where do you see <defunct> in his ps output? What does that have to do with this question?
    – Barmar
    Feb 6, 2015 at 19:42
  • @Barmar I didn't see. Unfortunately not always the problem is exactly where you are searching for. BTW from the $! he kill -9 without waiting the background process with a camera...after a sleep 16 he kill -9 the parent, abruptly again. It smelled of .zombie... Following the smell ( :-) ) you can see that, with the following ps -ef he did, the child still alive, but the parent was killed (-9).
    – Hastur
    Feb 7, 2015 at 8:19
  • 1
    I think you're confusing orphan processes with zombie processes, but they're unrelated.
    – Barmar
    Feb 7, 2015 at 13:18
  • Looking again the script: he kill -9 its own process. It reasonable to assume it's killed and < defunct >... even more after the non effective call sudo killall raspivid. It's even possible that raspivid spawns its own child processes that remain orphan. BTW it's enough to do "ps -aux | grep Z" to see if it is zombie or not, and it should be (enough) to avoid to kill -9 the process in the main script.
    – Hastur
    Feb 7, 2015 at 13:34
4

To answer question number 1:

When a process spawns child processes, the children each have their own PID. The PPID of each child (parent's process id) is the PID of their parent process. If the parent dies, then the child processes are orphaned. Orphaned processes are automatically picked up by the system init process which has a PID of 1.

0

The program probably has the camera device open, and by forcibly killing it, you haven't allowed it to clean up properly, so now it's stuck.

A few observations:

  • It's generally not a good idea to kill a program by starting with -9 unless you know what you're doing. Just a normal kill (with no options) is fine.
  • There should not be a need to do any killing in your script at all. You've already passed -t 15000 to the program to specify the length of the video, so the first kill should be unnecessary. The second kill is also unnecessary since the shell will exit on its own when it reaches the end of the script. If the program isn't exiting on its own (as it should), then you've got other problems.
0

Here is some trick I did to clean zombie process. I needed it because upgrade script of one package has been waiting with killall -pw but the process was zombie because gnome-session didn't do 'waitpid' on it. So I did it manually:

gdb
(gdb) attach <zombie parent PID>
(gdb) call waitpid( <zombie PID>, 0, 0)
(gdb) detach

That's it! Zombie process was clean up!

You must log in to answer this question.