【发布时间】:2020-07-12 05:13:05
【问题描述】:
我正在努力让 Redis 在 Solaris 10 上运行,但有一些集成测试失败了。我正在研究的测试是这样的:
- 启动 Redis
- 它分叉,子进程开始将数据库转储到备份文件 (RDB)
- 实际上,在孙子变成僵尸的情况下,父母/孩子/孙子的关系正在发生,但我注意到就在我不得不回家前几分钟。
- 一小段时间后,测试脚本将 SIGTERM 发送给孩子
- 孩子捕捉到信号并优雅地关闭
- The parent calls wait3()
尽管调用了wait3(),孩子最终还是处于僵尸状态。
当我运行测试时,大约 90% 的时间都失败了。一旦它进入失败状态,它就永远不会恢复。我尝试将测试更改为等待更长的时间,尽管它似乎在进程退出后多次调用 wait3(),但它一直保持该状态,直到父进程被杀死。
很遗憾,我要到下周才能再次处理这个问题,所以我正在家里研究它。我的大部分谷歌搜索都只找到了文档或“为什么进程会变成僵尸?”输入问题。
90 年代中期的This google groups thread 可能会有所帮助,尽管他们主要谈论的是 Solaris / SunOS 的旧版本。
【问题讨论】:
-
请注意:github.com/redis/redis/blob/…
exitFromChild()函数调用exit()如果COVERAGE_TEST已定义,但exitFromChild()由此处的信号处理程序调用:github.com/redis/redis/blob/…exit()不是async-signal-safe 并且不应从信号处理程序中调用,因此如果代码在编译时定义了COVERAGE_TEST,它应该绝不调用exitFromChild()。 -
在花了更多时间调试之后,我意识到我有一个错误的前提:它永远不会为第一个测试用例发送 SIGTERM 并且那个测试用例也失败了。我相信 RDB 传输过程意外死亡,所以主节点永远不会调用
wait
标签: redis solaris zombie-process