How can I kill a <defunct> process whose parent is init?

64,632

Solution 1

You cannot kill a <defunct> process (also known as zombie process) as it is already dead. The system keeps zombie processes for the parent to collect the exit status. If the parent does not collect the exit status then the zombie processes will stay around forever. The only way to get rid of those zombie processes are by killing the parent. If the parent is init then you can only reboot.

Zombie processes take up almost no resouces so there is no performance cost in letting them linger. Although having zombie processes around usually means there is a bug in some of your programs. Init should usually collect all children. If init has zombie children then there is a bug in init (or somehwere else but a bug it is).

http://en.wikipedia.org/wiki/Zombie_process

Solution 2

Anyone trying to fix the Transmission C source code should read about the "double fork" trick to avoid zombies and signal handlers ... and how it can be used as part of a smart variadic spawn function (see Spawning in Unix).

excerpt from: 
   "Spawning in Unix", http://lubutu.com/code/spawning-in-unix

Double fork
This trick lets you spawn processes whilst avoiding zombies, without 
installing any signal handler. The first process forks and waits for its 
child; the second process forks and immediately exits and is reaped;
the third process is adopted by init, and executes the desired program. 
All zombies accounted for, since init is always waiting.

if(fork() == 0) {
   if(fork() == 0) {
       execvp(file, argv);
       exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
}
wait(NULL);
Share:
64,632
Andy E
Author by

Andy E

I'm mainly a JavaScript coder, with some experience in other languages. My GitHub - https://github.com/andyearnshaw/Intl.js My Twitter - https://twitter.com/whattheheadsaid LinkedIn - https://uk.linkedin.com/in/andyearnshaw

Updated on September 18, 2022

Comments

  • Andy E
    Andy E over 1 year

    Transmission is intermittently hanging on my NAS. If I send SIGTERM, it doesn't disappear from the process list and a <defunct> label appears next to it. If I send a SIGKILL, it still doesn't disappear and I can't terminate the parent because the parent is init. The only way I can get rid of the process and restart Transmission is to reboot.

    I realize the best thing I can do is try and fix Transmission (and I've tried), but I'm a novice at compiling and I wanted to make sure my torrents finished before I start messing around with it.

    • JoelFan
      JoelFan about 13 years
      No one is stating the obvious... a <defunct> process owned by "init" should be impossible! This is a very strange situtation! Are you sure?
    • D.Shawley
      D.Shawley about 13 years
      @JoelFan: I was just looking that up to make sure that I wasn't forgetting something important. Zombies that are children of init should go away pretty quickly since init waits on children periodically as one of its many common tasks... is <defunct> the same as a zombie?
    • D.Shawley
      D.Shawley about 13 years
      nevermind ... <defunct> is precisely the same as a zombie. init will wait on its children so this should never happen in theory. I wonder what happens if you send a SIGCHLD to init?
    • Andy E
      Andy E about 13 years
      @JoelFan: yeah, I'm sure. The value for PPID was 1 (init), so it was impossible to SIGKILL the process.
    • tshepang
      tshepang almost 12 years
    • Sam
      Sam over 11 years
      This happens to me somewhat regularly on Ubuntu 11.04, like maybe once or twice a month on average. It is especially a problem when other processes find the zombie process and try using it. Two common examples that come to mind are the Google Talk Plugin and ADB (Android Debug Bridge). Their zombie processes somehow end up as child of init and I am unable to use things like G+ Hangouts or many Android development features until rebooting. I guess I just need to let go of GNOME 2 and upgrade (yes, I tried MATE & many others, nothing beats good old GNOME 2, yet).
  • D.Shawley
    D.Shawley about 13 years
    init can never have zombie children. From the wikipedia article: 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. One of init's responsibilities is reaping orphans and parentless zombies.
  • camh
    camh about 13 years
    @D.Shawley: init can have bugs though. The init replacement runit has had a bug that causes this issue.
  • Jander
    Jander almost 12 years
    The double fork prevents zombie processes by forcing the kernel to set its parent to PID 1, which is supposed to clean up zombies. It sounds like Transmission already does it, since its parent is already process 1.
  • Daco
    Daco almost 7 years
    init can have defunct children, maybe due to a bug, but it can. Because I am looking at one right now.
  • okaerin
    okaerin over 6 years
    There is this program which I ran from terminal and entered into defunct state.. As explained by @lesmana, when I closed the terminal(parent) the program exited cleanly.
  • Sean
    Sean over 3 years
    Update, November 2020 on Debian 10 for AMD64: Right now, I had to power off my machine because of an init child zombie process blocking me from using my computer. VMware Player hung. VMX spawns as a child of init. I killed it, but it went into zombie state as a child of init. No matter how many times I sent SIGCHLD to both VMX and init, the process never went away. It blocked me from using my desktop environment, so I had to shut it down. I logged in over SSH from my phone and issued reboot, but after 12 minutes the processes never stopped. I ended up hitting the power button.