У нас есть несколько большее C ++ приложение для macOS.Это приложение в какой-то момент имеет несколько потоков, которые вызывают fork
и почти сразу после этого exec
.Между fork
и exec
нет ничего особенного, только некоторые dup2
и close
труб, без блокировок, без динамического выделения.Другие потоки родительского процесса могут выполнять некоторое динамическое распределение при вызове 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 может быть причиной, поэтому мы попытались отключить это (добавив раздел __DATA,__objc_fork_ok
), но проблема все еще появляется.
Есть ли здесь кто-нибудьидея, что может быть причиной?
Пока что кажется, что fork
в многопоточной среде просто сломан на macOS.Эта проблема не случается слишком часто, просто иногда - чем больше это раздражает.Я не уверен, что может быть не так с нашей стороны - когда дочерний процесс продолжает зависать в системном коде, он даже не может выполнить наш код.
Одна идея - возможно, что fork
получитвызывается одновременно из нескольких потоков.Может ли это вызвать проблемы, может только один поток за один раз позвонить fork
?
Спасибо за любые мысли.