How Is It Possible That Kill -9 for a Process on Linux Has No Effect

How is it possible that kill -9 for a process on Linux has no effect?

As noted in comments to the OP, a process status (STAT) of D indicates that the process is in an "uninterruptible sleep" state. In real-world terms, this generally means that it's waiting on I/O and can't/won't do anything - including dying - until that I/O operation completes.

Processes in a D state will normally only be there for a fraction of a second before the operation completes and they return to R/S. In my experience, if a process gets stuck in D, it's most often trying to communicate with an unreachable NFS or other remote filesystem, trying to access a failing hard drive, or making use of some piece of hardware by way of a flaky device driver. In such cases, the only way to recover and allow the process to die is to either get the fs/drive/hardware back up and running so the I/O can complete or to give up and reboot the system. In the specific case of NFS, the mount may also eventually time out and return from the I/O operation (with a failure code), but this is dependent on the mount options and it's very common for NFS mounts to be set to wait forever.

This is distinct from a zombie process, which will have a status of Z.

Consequences of using kill -9 for node processes?

It doesn't give the process a chance to cleanly:

1) shut down socket connections

2) clean up temp files

3) inform its children that it is going away

4) reset its terminal characteristics

These are the bad consequences of what can happen when you use kill -9. You should only use kill -9 as a last resort if all else has failed.

And to the second question, because kill -9 will kill the process even if it is in the middle of doing something while kill will shutdown the process after a clean exit.

kill -9 doesn't work

Process will get the KILL signal (all signals behave in the same way) only and only when it is in "userspace". If it is in kernelspace (for example waiting for a NFS share to deliver data read from file), it will not get the signal (the signal will wait until process returns to userspace, it will not get lost).

Most NFSD's have some options regarding this, it can return from read with failure status if it times out. This will cause data loss (as will the other option..) because not all programs check for all read() results.

Processes can not ignore/cancel KILL signal, it's notification only and gives a chance to save any necessary data.

when a process is killed is this information recorded anywhere?

If your Linux kernel is compiled with the process accounting (CONFIG_BSD_PROCESS_ACT) option enabled, you can start recording process accounting info using the accton(8) command and use sa(8) to access the recorded info. The recorded information includes the 32 bit exit code which includes the signal number.

(This stuff is not widely known / used these days, but I still remember it from the days of 4.x Bsd on VAXes ...)

How to kill zombie process

A zombie is already dead, so you cannot kill it. To clean up a zombie, it must be waited on by its parent, so killing the parent should work to eliminate the zombie. (After the parent dies, the zombie will be inherited by pid 1, which will wait on it and clear its entry in the process table.) If your daemon is spawning children that become zombies, you have a bug. Your daemon should notice when its children die and wait on them to determine their exit status.

An example of how you might send a signal to every process that is the parent of a zombie (note that this is extremely crude and might kill processes that you do not intend. I do not recommend using this sort of sledge hammer):

# Don't do this.  Incredibly risky sledge hammer!
kill $(ps -A -ostat,ppid | awk '/[zZ]/ && !a[$2]++ {print $2}')

How to kill a process based on its argument

If you're on linux, use pkill with the string with args of the process you want to kill. The -f flag specifies to match the full string and args to the running process.

pkill -f "rsync -av /456"

Any other flavor of *nix, use ps with flags, pipe to grep, pipe to awk to pull the process id, then pipe to kill.

How to create a process which kills it's parent and making some actions after that

Unfortunately, no one provides answer. So looks like it's not possible to implement it via the standard process model, but I solved it via running the separate daemon (background service) which is triggered by the main process, kill it and replaces with the new updated version and making it up and running again.

Related Topics

Leave a reply