【问题标题】:Process stuck in exit, shows as zombie but cannot be reaped进程卡在退出中,显示为僵尸但无法收割
【发布时间】:2013-09-27 20:33:51
【问题描述】:

我有一个由其父进程监控的进程。孩子遇到一个错误,导致它调用abort。该进程不会篡改中止进程,因此它应该按预期进行(转储核心,终止)。父母应该检测到孩子的终止并触发一系列事件来响应失败。子进程是多线程且复杂的。

这是我从ps看到的:

F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0  1000  4929  1272  20   0  85440  6792 wait   S+   pts/2      0:00 rxd
1  1000  4930  4929  20   0      0     0 exit   Zl+  pts/2     38:21 [rxd] <defunct>

所以孩子 (4930) 已经终止。这是一个僵尸。正如预期的那样,我无法附加到它。但是,父级 (4929) 仍被阻止:

int i;
// ...
waitpid (-1, &i, 0);

所以看起来孩子是一个僵尸,但不知何故还没有完成它的父母收割它所需的一切。我认为exitWCHAN 字段是一个有价值的线索。

平台为 64 位 Linux,Ubuntu 13.04,内核 3.8.0-30。孩子似乎没有倾倒核心或做任何事情。我已经离开系统几分钟,没有任何变化。

有没有人知道可能是什么原因造成的,或者我能做些什么?

更新:另一个有趣的信息——如果我kill -9父进程,子进程就会消失。这有点令人费解,因为父进程是微不足道的,只是阻塞在waitpid 中。另外,当这个问题发生时,我没有得到任何核心转储(来自孩子)。

更新: 孩子似乎被困在schedule,从exit_mm 调用,从do_exit 调用。我想知道为什么exit_mm 会打电话给schedule。我想知道为什么杀死父母会解开它。

【问题讨论】:

  • 什么给了你ps -eo wchan,pid | grep 4930
  • WCHAN 字段在上面。孩子在exit,父母在wait。相信孩子莫名其妙卡在内核的exit函数中,无法完成完全终止的过程。
  • 哦,是的,我现在明白了。您是否在子进程中使用信号处理程序?可能是它在退出期间挂在阻塞 IO 上吗?很高兴看到孩子的代码,但你说它太复杂了..没有机会把它分解成更简单的代码?
  • @hek2mgl 我无法在简单的条件下复制它。我想它有可能挂在 I/O 上,但是在映射消失后内核会在 exit 上做什么 I/O?我们确实使用了信号处理程序,但是对std::_exit 的调用已经发生并且内核已经接管了终止进程(因为该进程是僵尸进程,我们知道它没有运行任何用户空间代码)。
  • 你能用其他内核重现它吗? (其他发行版,自编译,...)?

标签: linux ubuntu exit


【解决方案1】:

我终于明白了!这个过程实际上一直在做有用的工作。该进程保存了对 slow 文件系统上的 large 文件的最后引用。当进程终止时,对文件的最后引用是释放,强制操作系统回收空间。该文件太大,需要数万次 I/O 操作,耗时 10 分钟或更长时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 2016-12-13
    • 1970-01-01
    • 2013-12-30
    • 2013-04-11
    • 1970-01-01
    • 2010-12-26
    相关资源
    最近更新 更多