如果父级在google_breakpad :: ExceptionHandler :: SignalHandler中崩溃或退出,则子级会挂起

时间:2014-10-29 13:36:33

标签: linux google-breakpad

如果在克隆子进程后父进程崩溃,但在使用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();
...
  1. 将一个处理过的信号发送给父(例如SIGSEGV),以便上述GenerateDump(...)方法。
  2. 观察父项已退出但子项仍然存在,已在WaitForContinueSignal()上阻止。
  3. 上述步骤的输出

    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个问题

    1. 是否是破坏物库保持儿童活着的预期行为?我的期望是孩子应该在父母崩溃/退出后立即退出。
    2. 如果不是预期的行为,在父崩溃/退出后完成客户端的最佳解决方案是什么?
    3. 提前致谢!

1 个答案:

答案 0 :(得分:0)

关于可能的解决方案的任何线索?

这也可能在关机崩溃期间发生,如果崩溃的线程不是主要的,并且父进程正好在这个时间段从main()退出,所以显然它不太可能发生,因为它看起来乍一看。

此时此刻,我认为这是因为clone()函数的CLONE_FILES标志而发生的。这导致如果父进程退出,子进程中的read()不返回EOF的情况。

如果我们可以在clone()调用中安全地摆脱这个标志,我还没有完成检查。

相关问题