如果在克隆子进程后父进程崩溃,但在使用SendContinueSignalToChild()
发送解除阻塞的字节之前崩溃,则会发生这种情况。在这种情况下,管道文件句柄保持打开状态,并且read(...)
内的WaitForContinueSignal()
处的子项无限制地被阻止。崩溃后,子进程被init进程采用。
重现的步骤:
1。在google_breakpad::ExceptionHandler::GenerateDump(CrashContext *context)
模拟父级崩溃:
...
const pid_t child = sys_clone(
ThreadEntry, stack, CLONE_FILES | CLONE_FS | CLONE_UNTRACED, &thread_arg, NULL, NULL, NULL);
int r, status;
// Allow the child to ptrace us
sys_prctl(PR_SET_PTRACER, child, 0, 0, 0);
int *ptr = 0;
*ptr = 42; // <------- Crash here
SendContinueSignalToChild();
...
GenerateDump(...)
方法。WaitForContinueSignal()
上阻止。上述步骤的输出:
dmytro@db:~$ ./test &
[1] 25050
dmytro@db:~$ Test: started
dmytro@db:~$ ps aflxw | grep test
0 1000 25050 18923 20 0 40712 2680 - R pts/37 0:13 | | \_ ./test
0 1000 25054 18923 20 0 6136 856 pipe_w S+ pts/37 0:00 | | \_ grep --color=auto test
dmytro@db:~$ kill -11 25050
[1]+ Segmentation fault (core dumped) ./test
dmytro@db:~$ ps aflxw | grep test
0 1000 25058 18923 20 0 6136 852 pipe_w S+ pts/37 0:00 | | \_ grep --color=auto test
1 1000 25055 1687 20 0 40732 356 pipe_w S pts/37 0:00 \_ ./test
1687是init pid。
在现实世界中,崩溃发生在与处理信号的线程平行的线程中。
注意:由于正常的程序终止(即在并行线程中调用exit(0)
),也会发生此问题。
在Linux 3.3.8-2.2。,mips和i686平台上测试过。
所以,我的2个问题:
提前致谢!
答案 0 :(得分:0)
关于可能的解决方案的任何线索?
这也可能在关机崩溃期间发生,如果崩溃的线程不是主要的,并且父进程正好在这个时间段从main()退出,所以显然它不太可能发生,因为它看起来乍一看。
此时此刻,我认为这是因为clone()函数的CLONE_FILES标志而发生的。这导致如果父进程退出,子进程中的read()不返回EOF的情况。
如果我们可以在clone()调用中安全地摆脱这个标志,我还没有完成检查。