首页 > 解决方案 > macOS上线程中断的fork + exec进程?- 子进程卡在 _atfork_child 中

问题描述

我们有一个更大的用于 macOS 的 C++ 应用程序。这个应用程序在某些时候有多个线程,该调用fork几乎是在此之后立即调用的execfork和之间没有什么特别的exec,只是一些管道dup2close没有锁,没有动态分配。其他父进程线程在被调用时可能会进行一些动态分配fork,但我认为这无关紧要。

我们有时会看到,在 fork 之后,子进程甚至没有从 中唤醒fork,它挂了很长时间,当我们将调试器附加到它时,我们会看到以下堆栈跟踪:

* thread #1, stop reason = signal SIGSTOP
  * frame #0: 0x00007fff79e0234a libsystem_kernel.dylib`syscall_thread_switch + 10
    frame #1: 0x00007fff79e7926a libsystem_malloc.dylib`tiny_malloc_should_clear + 547
    frame #2: 0x00007fff79e78f96 libsystem_malloc.dylib`szone_malloc_should_clear + 66
    frame #3: 0x00007fff79e7a188 libsystem_malloc.dylib`malloc_zone_calloc + 99
    frame #4: 0x00007fff79e7a108 libsystem_malloc.dylib`calloc + 30
    frame #5: 0x00007fff79da4a62 libsystem_coreservices.dylib`_dirhelper_init + 460
    frame #6: 0x00007fff79eafacb libsystem_platform.dylib`_os_once_callout + 18
    frame #7: 0x00007fff79da5ebb libsystem_coreservices.dylib`_libcoreservices_fork_child + 52
    frame #8: 0x00007fff76a1bb09 libSystem.B.dylib`libSystem_atfork_child + 39
    frame #9: 0x00007fff79d26d97 libsystem_c.dylib`fork + 40
...

因此,如果我理解正确,子进程甚至没有从fork.

AFAIK 我们的应用程序没有做任何特别的事情,例如安装自定义 atfork 处理程序等。我们不使用 Objective C 的东西。我认为Objective C 的这种新的 fork 行为可能是原因,所以我们尝试禁用它(添加__DATA,__objc_fork_ok部分),但问题仍然出现。

这里有人知道可能是什么原因吗?

到目前为止,fork在多线程环境中似乎只是在 macOS 上被破坏了。这个问题不会经常发生,只是有时 - 它越烦人。我不确定我们这边出了什么问题——当子进程一直挂在系统代码中时,它甚至无法执行我们的代码。

一个想法 - 有可能fork从多个线程同时调用。这会导致问题,一次只能调用一个线程fork吗?

感谢您的任何想法。

标签: c++multithreadingmacosforkexec

解决方案


推荐阅读