Исключаются ли исключения "EXC_BREAKPOINT (SIGTRAP)" из-за отладки контрольных точек?

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

Date/Time:       2010-04-06 11:44:56.106 -0700
OS Version:      Mac OS X 10.6.3 (10D573)
Report Version:  6

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   com.apple.CoreFoundation        0x90ab98d4 __CFBasicHashRehash + 3348
1   com.apple.CoreFoundation        0x90adf610 CFBasicHashRemoveValue + 1264
2   com.apple.CoreText              0x94e0069c TCFMutableSet::Intersect(__CFSet const*) const + 126
3   com.apple.CoreText              0x94dfe465 TDescriptorSource::CopyMandatoryMatchableRequest(__CFDictionary const*, __CFSet const*) + 115
4   com.apple.CoreText              0x94dfdda6 TDescriptorSource::CopyDescriptorsForRequest(__CFDictionary const*, __CFSet const*, long (*)(void const*, void const*, void*), void*, unsigned long) const + 40
5   com.apple.CoreText              0x94e00377 TDescriptor::CreateMatchingDescriptors(__CFSet const*, unsigned long) const + 135
6   com.apple.AppKit                0x961f5952 __NSFontFactoryWithName + 904
7   com.apple.AppKit                0x961f54f0 +[NSFont fontWithName:size:] + 39

(... далее текст)

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

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

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

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

Ответ 1

Являются ли исключения "EXC_BREAKPOINT (SIGTRAP)" вызваны отладкой контрольных точек?

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

SIGTRAPs обычно вызваны выбросами NSE, но не всегда - возможно даже непосредственно raise.

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

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

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

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

Нет.

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

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

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

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

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

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

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

Это так. Контрольные точки отладчика работают только в отладчике.

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

Нет.

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

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

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

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

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

  • один, используя Xcode около года назад.
  • другой, использующий Visual С++ около 15 лет назад.

Ответ 4

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