Исключения «EXC_BREAKPOINT (SIGTRAP)» вызваны точками останова отладки?

85

У меня есть многопоточное приложение, которое очень стабильно на всех моих тестовых машинах и кажется стабильным почти для каждого из моих пользователей (на основе отсутствия жалоб на сбои). Однако приложение часто дает сбой для одного пользователя, который любезно отправил отчеты о сбоях. Все отчеты о сбоях (~ 10 последовательных отчетов) выглядят практически одинаково:

(.... следует еще текст)

Во-первых, я потратил много времени на изучение [NSFont fontWithName: size:]. Я подумал, что, возможно, пользовательские шрифты каким-то образом облажались, поэтому [NSFont fontWithName: size:] запрашивал что-то несуществующее и по этой причине не работал. Я добавил кучу кода, используя [[NSFontManager sharedFontManager] availableFontNamesWithTraits: NSItalicFontMask], чтобы заранее проверить наличие шрифта. К сожалению, эти изменения не устранили проблему.

Теперь я заметил, что забыл удалить некоторые точки останова отладки, в том числе _NSLockError, [NSException raise] и objc_exception_throw. Однако приложение определенно было построено с использованием «Release» в качестве активной конфигурации сборки. Я предполагаю, что использование конфигурации «Release» предотвращает установку любых точек останова - но опять же, я не уверен, как именно работают точки останова и нужно ли запускать программу изнутри gdb, чтобы точки останова имели какой-либо эффект.

У меня следующие вопросы: может ли мой выход из установленных точек останова быть причиной сбоев, наблюдаемых пользователем? Если да, то почему точки останова могут вызывать проблемы только у этого пользователя? Если нет, то были ли у кого-нибудь подобные проблемы с [NSFont fontWithName: size:]?

Я, вероятно, просто попробую удалить точки останова и отправить обратно пользователю, но я не уверен, сколько валюты у меня осталось у этого пользователя. И я хотел бы в более общем плане понять, может ли оставление установленных точек останова вызвать проблему (когда приложение построено с использованием конфигурации «Release»).

Деннис
источник

Ответы:

189

Исключения «EXC_BREAKPOINT (SIGTRAP)» вызваны точками останова отладки?

Нет. На самом деле, наоборот: SIGTRAP (трассировочная ловушка) заставит отладчик прервать (прервать) вашу программу точно так же, как и фактическая точка останова. Но это потому, что отладчик всегда ломается при сбое, а SIGTRAP (как и несколько других сигналов ) является одним из типов сбоев.

SIGTRAP обычно вызываются генерированием исключений NSException, но не всегда - их даже можно напрямую поднять самостоятельно.

Теперь я заметил, что забыл удалить некоторые точки останова отладки, в том числе _NSLockError, [NSException raise] и objc_exception_throw.

Это не точки останова. Две из них - это функции и -[NSException raise]метод.

Вы имели в виду, что установили точки останова для этих функций и этого метода?

Я предполагаю, что использование конфигурации «Release» предотвращает установку любых точек останова -

Нет.

Конфигурации представляют собой конфигурации сборки . Они влияют на то, как Xcode создает ваши приложения.

Точки останова не являются частью сборки; вы устанавливаете их в отладчике. Они только существуют, только попадают в них и останавливают вашу программу только тогда, когда вы запускаете свою программу под отладчиком.

Поскольку они не являются частью сборки, невозможно передать ваши точки останова пользователю, просто предоставив ему пакет приложения.

Я не совсем понимаю, как работают точки останова ...

Когда ваша программа достигает точки останова, отладчик прерывает (прерывает) вашу программу, после чего вы можете проверить состояние программы и осторожно продвинуться вперед, чтобы увидеть, как программа работает неправильно.

Так как отладчик останавливает вашу программу, точки останова не действуют, если вы не запускаете свою программу под отладчиком.

… Или нужно ли запускать программу изнутри gdb, чтобы точки останова работали.

Оно делает. Точки останова отладчика работают только в отладчике.

У меня следующие вопросы: может ли мой выход из установленных точек останова быть причиной сбоев, наблюдаемых пользователем?

Нет.

Во-первых, как уже отмечалось, даже если эти точки останова каким-то образом были перенесены в систему пользователя, точки останова действуют только в отладчике. Отладчик не может остановиться на точке останова, если ваша программа не работает под отладчиком. Пользователь почти наверняка не запускает ваше приложение под отладчиком, особенно после того, как он вылетел из него.

Даже если они не запустить приложение под отладчиком со всеми из этих точек останова , установленным, точка останова только хит , когда ваша программа достигает этой точки, так что одна из этих точек останова может стрелять только если вы или какао называется _NSLockError, -[NSException raise]или objc_exception_throw. Достижение этой точки не было бы причиной проблемы, это было бы ее симптомом.

И если вы действительно упали в результате вызова одного из них, в вашем журнале сбоев будет указано хотя бы одно из них. Это не так.

Таким образом, это не было связано с вашими точками останова (другая машина, отладчик не задействован), и это не было исключением какао - как я уже упоминал, исключения какао являются одной из причин SIGTRAP, но не единственной. Вы столкнулись с другим.

Если нет, то были ли у кого-нибудь подобные проблемы с [NSFont fontWithName: size:]?

Мы не можем определить, были ли у нас похожие проблемы, потому что вы отключили журнал сбоев. Мы ничего не знаем о том, в каком контексте произошел сбой.

Единственное, что можно вырезать, - это раздел «Двоичные изображения», поскольку у нас нет ваших пакетов dSYM, а это значит, что мы не можем использовать этот раздел для обозначения журнала сбоев.

Вы же можете. Я написал для этого приложение ; загрузите в него журнал сбоев, и он должен автоматически обнаружить пакет dSYM (вы сохраняете пакет dSYM для каждой распространяемой сборки выпуска, верно?) и восстанавливать имена ваших функций и методов в трассировке стека, где бы ни появлялись ваши функции и методы.

Для получения дополнительной информации см. Руководство по отладке Xcode .

Питер Хози
источник
3
Вау, спасибо за исчерпывающий ответ. • «Вы имели в виду, что устанавливаете точки останова для этих функций ...» Да, это то, что я имел в виду. • «Точки останова не являются частью сборки ... Они существуют только, достигаются только и останавливают вашу программу только тогда, когда вы запускаете свою программу под отладчиком» Спасибо, это именно то, что я хотел знать. • «символизировать журнал сбоев ... Я написал для этого приложение» Хорошее приложение. Я обычно "символизирую" чисто интуитивно, но ваше приложение лучше! • Я пришел к выводу, что это какая-то проблема со шрифтом пользователя, и буду работать над этим с этой точки зрения.
Деннис
7

Весьма вероятно, что у этого пользователя установлен поврежденный шрифт. Трассировка стека определенно подтверждает эту гипотезу, как и тот факт, что она затрагивает только одного пользователя.

В этом случае вы мало что можете сделать, кроме как заставить пользователя удалить неправильный шрифт, поскольку возникающие сбои происходят глубоко в коде Apple.

Попробуйте заставить пользователя запустить проверку шрифта в Font Book. Для этого запустите Font Book, нажмите All Fonts в списке источников и затем выберите все перечисленные шрифты. Затем вы можете выбрать « Проверить шрифты» в меню « Файл» .

Роб Кенигер
источник
1
Спасибо за этот совет о Font Book - я очень мало знаю о шрифтах, и мне было интересно проверить свои собственные шрифты ... Я предлагаю пользователю попробовать это.
Деннис
0

Точки останова не записываются в двоичный файл. Скорее всего, у этого человека не работает установка ОС. Проверьте журналы консоли на наличие dyld-сообщений.

Азим Батт
источник
Спасибо за такой быстрый ответ! Обдумывая эту проблему в Google, я заметил, что у других есть EXC_BREAKPOINTS, связанные с dyld-сообщениями, но мои журналы сбоев не показывают никаких сообщений от dyld.
Деннис
0

У меня была такая же ошибка. По необъяснимой причине точка останова была ответственна за выброс EXC_BREAKPOINT исключения . Решением было удалить точку останова, и тогда код заработал.

EXC_BREAKPOINT - это тип исключения, которое используют отладчики. Когда вы устанавливаете точку останова в своем коде, компилятор вставляет исключение этого типа в исполняемый код. Когда выполнение достигает этой точки, генерируется исключение, и отладчик его перехватывает. Затем отладчик показывает ваш код в строке с точкой останова. Так работают отладчики. Но в этом случае отладчик некорректно обрабатывает исключение и отображается как обычная ошибка исключения.

Я встречал эту ошибку два раза в жизни:

  • один использовал Xcode около года назад.
  • другой использовал Visual C ++ около 15 лет назад.
Веладан
источник
Странно, что я получил эту ошибку вообще без точек останова.
kelin
Я не говорю, что эта ошибка возникает только с точками останова: EXC_BREAKPOINT может произойти по нескольким причинам. Я объясняю пару очень редких случаев, когда точка останова генерирует необработанное исключение.
veladan