从进程表中删除僵尸进程

ske*_*rit 8 linux kill process zombie

我有一个烦人的僵尸进程,它被 init 采用,它不会消失。我读过有一种方法可以创建一个虚拟进程,将僵尸附加为该新进程的子进程,然后杀死它,将其从进程表中删除。

我将如何做到这一点,准确地说?

是的,我已经阅读了大部分内容:

僵尸进程已经死了,所以它不能被杀死。

或者

你应该重启你的系统

僵尸进程不使用任何资源,您应该让它们使用

不幸的是,许多程序检查进程表以查看实例是否已经在运行,如果进程表中有条目,则将拒绝启动新的实例。

每次我的 SSHFS 连接断开时重新启动,带着 Sublime,有点傻。

vor*_*aq7 17

摆脱僵尸的唯一方法是创建它的父级,wait()以便它可以报告其退出状态。您可以通过发送SIGCHLD给父级来做到这一点,假设父级写入正确。

如果你有僵尸,通常意味着父级没有正确写入(因为子级SIGCHLD在它死后变成了僵尸时已经发送给了它的父级),所以下一步是杀死父级。
pstree(带有-p选项)这样的工具可以向您显示僵尸的血统,以便您知道哪个进程是父进程。
当父母死亡时,僵尸会被 收养init,它总是wait()让孩子死去,并且会很高兴地杀死所有它收养的僵尸。

如果父进程实际上init已经是(PID 1),那么您就处于一种永远不会发生的情况。您可以尝试发送SIGCHLDinit,但您真的不应该这样做,如果这不起作用,您唯一的办法就是重新启动,因为您的系统init已损坏并且无法正常工作。

(这些是“霰弹枪”选项。)


如果你想避免杀死父进程,一些比我更有创意的人也提出了这个选项:

  1. 确定僵尸进程和父进程的 PIDS
    (在这个例子中,假设僵尸进程是 PID 3101,父进程是 PID 3100)
  2. 火起来gdbattach父:
    attach 3100
  3. 召唤waitpid僵尸:
    call waitpid(3101,0,0)
  4. 从父级 ( detach)分离并退出调试器。

(这是一支经过精心调整的狙击步枪。)