如何杀死父级为PID = 0的僵尸进程?

时间:2016-06-01 20:12:28

标签: macos zombie-process

通常,在OSX上运行LLDB时,调试器会偶尔崩溃(这似乎是LLDB的本质)。当发生这种情况时,我得到一个看起来很奇怪的僵尸进程(我正在调试的进程)。它有父PID = 0:

我的流程叫做:worker

以下是ps aux | grep worker

的输出
root            22785   0.0  0.0        0      0   ??  Z     3:48pm   0:00.00 (worker)

如您所见,该进程具有PID,但它没有父PID。这什么都不做

sudo kill -9 <pid>

事实上,重新启动似乎摆脱了它。我该如何杀死这样的流程?我需要让流程死掉,因为它可以保留我需要的端口。

3 个答案:

答案 0 :(得分:1)

Zombie 是已经死亡的进程的名称。因此,他们不再运行并且不再消耗系统资源。它们仅列在流程表中,在 zombie 流程完成运行时无法正确更新。这也是他们没有被分配给任何有意义的父母的原因。
因此,你不能再次杀死 zombie (正如他们的名字所暗示的那样,与中级恐怖电影中发生的情况相反:-))。在大多数操作系统中,等待一段时间 zombie 进程从进程列表中消失就足够了。或者如果你不能忍受这种情况,你必须重新启动。

请放心,僵尸对你没有任何伤害。

答案 1 :(得分:1)

情况是,作为用户,清除僵尸进程是不可能的;如果可能的话,内核会在准备就绪时处理它。

详见Mac OS X and iOS Internals

  

这是一个完全正常的状态,每一个过程通常都会花费无限的时间,就在它能够平静地休息之前......那些比他们的孩子更长久但却放弃其他事情的父母会诅咒这些孩子陷入僵尸的准死态。从各方面来看,僵尸都已经死了。

由于调试器充当其目标进程的父进程,该目标进程拥有一个网络端口并且调试器已崩溃,因此它使目标进程处于僵尸状态。这里的问题是调试器崩溃。

答案 2 :(得分:0)

需要做的是附加到正在运行的父级。 Init应该为你清理这些过程。

我们可以通过以下方式创建一个已失效的流程:

bash$ (sleep 1 & exec /bin/sleep 5000) &

现在我们可以检查我们已解散的过程:

$ ps -C sleep
PID TTY          TIME CMD
22582 pts/3    00:00:00 sleep
22583 pts/3    00:00:00 sleep <defunct>

所以我们必须得到孩子的父ID。在这种情况下,这很简单,但如果您不了解父母,我们可以使用ps -o ppid= 22583

因此,一旦获得此信息,您就可以附加到父级call waitpid()

$ gdb
(gdb) attach 22582
(gdb) call waitpid(22583,0,0)
$1=22583
(gdb) detach
(gdb) quit

我们可以看到已使用其他ps -C sleep

清除已解散的进程
 PID TTY          TIME CMD
22582 pts/3    00:00:00 sleep

我希望这会有所帮助。

编辑:僵尸不占用资源。然而,他们 DO 在内核的进程表中占用一个插槽,如果那里没有更多的空间,则可能无法启动另一个进程。