Подпроцесс NSTask застрял в _dyld_start

Я использую NSTask для запуска своего вспомогательного приложения. На 99% одной из моих клиентских систем это работает нормально, но две ответили мне, сообщив мне, что это не так. Один из них был достаточно хорош, чтобы позволить мне изучить проблему для каждого удаленного рабочего стола.

Я испробовал множество различных комбинаций NSPipe/NSFileHandle для StandardOutput/StandardError, чтобы убедиться, что проблема не связана с заполнением этих буферов. Пример 1 и 2. Я предполагаю, что это не связано, потому что он отлично работает на многих системах, а _dyld_start находится слишком рано в жизненном цикле приложения, чтобы заполнять StandardOutput/StandardError.

Другие заметки о проблеме:

  • Запуск вспомогательного приложения из терминала работает нормально.
  • Присоединение и отсоединение gdb от зависшего процесса и после его завершения работает нормально, а когда оно завершено, NSTask возобновляет работу после -waitUntilExit.
  • Использование fork(2) и execv(3) вместо NSTask позволяет нормально запустить и запустить помощник.
  • Родительский процесс находится в песочнице, но я думаю, что предыдущие отчеты не были изолированы в Mac OS X 10.6/10.7.

Скриншот процесса Пример из Activity Monitor:

Монитор активности

Приветствуются любые подсказки или советы по отладке, чтобы выяснить, почему помощник застрял в _dyld_start!


person catlan    schedule 10.03.2013    source источник
comment
Почему вы публикуете изображения текстовых данных? Скопируйте и вставьте текстовый пример отчета. Кроме того, проверьте сообщения журнала консоли. И проверьте наличие DYLD_* переменных среды.   -  person Ken Thomases    schedule 10.03.2013
comment
Присоединяюсь к рекомендации проверить консоль. Переменные среды DYLD_, если вы не устанавливаете их самостоятельно, смотрите в ~/.MacOSX/environment.plist.   -  person Peter Hosey    schedule 11.03.2013
comment
Консоль ничего не показала. Проверю DYLD_ в следующий раз, когда получу доступ к машине.   -  person catlan    schedule 12.03.2013
comment
Симптом идентичен тому, что произойдет, если вы используете posix_spawn для запуска приложения и указываете флаг POSIX_SPAWN_START_SUSPENDED, особенно потому, что присоединение, а затем отсоединение gdb открепляет вещи. Однако NSTask не использует posix_spawn, если только не используется какая-то его модифицированная версия.   -  person bdash    schedule 20.03.2013
comment
И, подумав об этом еще немного, я не понимаю, как переменные DYLD_ могут иметь значение, учитывая, что процесс остановлен до того, как dyld начал выполнение.   -  person bdash    schedule 21.03.2013
comment
@bdash спасибо за ваши комментарии! Проверил, нету зависания NSTask. Любая идея, если я могу выяснить, был ли установлен какой-то приостановленный флаг над отладчиком?   -  person catlan    schedule 21.03.2013
comment
Если вы можете предоставить sysdiagnose, пока процесс находится в этом состоянии, то у него может быть достаточно информации, чтобы понять, как он туда попал. В противном случае у нас просто не будет достаточно информации, чтобы сделать что-то большее, кроме предположений о том, что вызывает проблему.   -  person bdash    schedule 21.03.2013
comment
Самый простой способ запустить sysdiagnose: ⇧⌃⌘⌥. (shift-ctrl-cmd-opt-период).   -  person Peter Hosey    schedule 26.03.2013
comment
Я прошу sysdiagnose, но сердце не возвращается ...   -  person catlan    schedule 26.03.2013


Ответы (1)


Поскольку никто не ответил, я подкину несколько идей. Возможно, один из них является ответом — только предположение — но, поскольку подсказки и подсказки приветствуются, вы можете взглянуть на:

  • список загруженных библиотек в аварийном дампе (там может быть подсказка)
  • любая ошибка, которая может произойти в дочернем процессе (после форка). Тем не менее, я понимаю, почему может быть трудно вернуть любую ошибку после форка.

Если я правильно помню, NSTask вызывает posix_spawn(2). Это может быть подсказкой, поскольку использование fork(2) и execv(3) кажется эффективным, вы можете сосредоточиться на различиях между NSTask и неблокирующей альтернативой. Ясно, что в самом начале происходит что-то, что мешает ребенку выполнять правильно.

  • Вы уверены, что он застрял и не разбился? Насколько мог судить пользователь, ваше приложение не выглядело так, как будто оно потерпело крах. Только дочерний процесс рухнет.
  • В крайнем случае, вы можете попытаться найти любое возникающее исключение Mach (если оно возникнет, это будет означать ошибку, которую вы все равно не сможете исправить. Но, тем не менее, это даст ценные подсказки).
  • Вы можете сказать желающим заказчикам, чтобы они прислали вам их sysdiagnose.
    Для этого попросите их нажать Command + Option + Control + . + Shift, чтобы подождать несколько минут. Вскоре после этого их искатель должен открыть окно, чтобы показать файл с именем: sysdiagnose_timestamp_.tar.gz. Пожалуйста, попросите их отправить его вам по почте. У меня около 5 МБ. Дополнительные сведения см. на справочной странице sysdiagnose< /а>.
person Jean    schedule 25.03.2013
comment
@catlan у вас было время изучить одно или несколько предложений (особенно sysdiagnose)? - person Jean; 27.03.2013
comment
Могу ли я использовать текст в вашем вопросе как в списках рассылки Apple? Там есть несколько инженеров из Apple, которые могут помочь. - person Jean; 27.03.2013
comment
Я прошу моего клиента провести sysdiagnose, но сердце не возвращается ... Не стесняйтесь спрашивать в списке рассылки. Пожалуйста, разместите здесь ссылку на ветку списка рассылки, чтобы я тоже мог следить за ней. - person catlan; 28.03.2013