奇怪的僵尸进程响应信号?

奇怪的僵尸进程响应信号?

我有一个奇怪的情况。

我有一个用 C 编写的程序“A”,它以其他可执行文件的名称作为参数,例如“B”、“C”、“D”等。“A”的主要工作是分叉并启动“B” 、“C”等,然后检查它们是否崩溃,在这种情况下重新启动崩溃的进程。

此外,进程“A”运行一个单独的线程用于 RTC 同步目的。 “A” 开头为/bin/sh -c A B C D etc

我在嵌入式环境中,并且使用源自 Linux 4.4.57 的定制内核。

现在问题来了:有时我的进程“A”会变成僵尸!

我的一些观察:

  • 启动“A”的父进程/bin/sh -c仍然存在;
  • 子进程“B”、“C”等均未死亡;
  • “A”对信号做出反应;
  • 如果我杀死父进程/bin/sh -c,“A”的父进程将变为 init (1),但该进程仍然是僵尸进程;
  • 杀死僵尸“A”的唯一方法是发出kill -9 «pid-of-A»;
  • RTC 同步线程仍在运行!;

现在,由于“A”响应信号并且内部线程仍在运行,这个僵尸进程快要把我逼疯了。

如何解释这种行为?可能与内核构建配置有关?

编辑:我仔细查看了代码,发现“A”是使用以下命令作为守护进程启动的: start-stop-daemon -b --start --quiet --pidfile /var/run/A.pid --background --exec /bin/sh -- -c "A B C D > /var/log/log 2>&1"

更新:我已经能够通过调用 pthread_exit() 来复制相同的行为。问题是我在原始源上找不到任何对 phread_exit 的引用。主线程是否有其他方法可以停止让所有其他线程保持活动状态?

答案1

僵尸进程是一个已完成的进程,但在进程表中仍然有一个条目,因为例如它的子进程仍然活着(请参阅维基百科)。

所以,如你所说,如果B、C、D都没有死,而A执行完毕,那么它将成为僵尸,直到B、C、D也都执行完毕。

这是正常行为。

所以这看起来像是 A 中的一个错误:当它的孩子还活着时,它不应该死,因为它应该监视孩子。修复A的bug,不用担心它变成僵尸了。

答案2

pthread_exit()如果您在函数中使用main()这个帖子表明主线程可能进入僵尸状态,但其他线程继续运行。由于召唤pthread_exit()main()完全合法的,我认为这是正常情况,而且这个特殊的不死生物是无害的。您可以忽略它,或者等待其他线程main()而不是在pthread_exit()那里使用。

答案3

我通过查看 dmesg 找到了问题和问题的解决方案:我发现有一个“内部错误:哎呀:817 [#1] ARM”,是由 proc 文件中的自定义内核函数引起的。 proc文件被成为僵尸的进程的主线程读取,有时这个操作导致主线程死掉......这与@muru的答案完全相同。我修复了该功能,现在该进程不再终止。无论如何,谢谢大家。

相关内容