Xcode не показывает строку, которая вызывает сбой

126

Каждый раз, когда в моем приложении происходит сбой, Xcode выделяет вызов UIApicationMain () в функции main () как строку, вызвавшую сбой. В некоторых случаях это было нормально (например, ошибка сегментации), но сбой, с которым я пытаюсь справиться, - это простой SIGABRT с подробной информацией, записанной в консоли:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFDictionary setObject:forKey:]: attempt to insert nil value (key: Date)'

Xcode использовался для правильного отображения строки со старыми SDK, но с тех пор, как я обновился до Xocde 4.2, это изменилось. Совершенно очевидно, что Xcode точно знает, что вызвало сбой (или мог знать), но все еще не показывает фактическую строку. Есть ли какое-нибудь исправление или обходной путь для этого?

JonasG
источник
2
Вы компилируете для выпуска? В таком случае попробуйте установить схему на Отладка.
epatel
Также может быть, что какой-то xib является плохим, что приводит к сбою программы в месте вне вашего собственного исходного кода, таким образом, не показывая никаких файлов. Ошибка описывает проблему для словарного ключа с именем «Дата»
epatel
1
Apple должна нанять больше тестеров;)
Амр Лотфи

Ответы:

301

Вы также должны убедиться, что у вас установлены точки останова для всех исключений. Это заставит Xcode остановиться на строке, где возникает исключение. Сделайте следующее [в Xcode 4]:

  1. В навигаторе проекта в левой части Xcode щелкните навигатор точки останова (почти полностью до правой стороны верхней панели кнопок. Значок выглядит как толстая стрелка вправо).

  2. Внизу навигатора нажмите кнопку «+».

  3. Щелкните «Добавить исключительную точку останова».

  4. Будет создана новая точка останова. Его следует настроить по мере необходимости, но вы можете настроить его поведение.

  5. Запустите свой проект и воспроизведите исключение.

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

возчик
источник
4
Я новичок и почти месяц без этого развивался ... это меняет мою жизнь.
Джонни Бургер
4
Мой друг зарегистрировался для учетной записи SO, чтобы проголосовать за этот пост.
Alex Spencer
1
в моей книге это называется половинной задницей о яблоках
ChuckKelly
1
Сделал это, но до сих пор не могу найти, где он вызвал длину на
нуле
1
Это работает, но недостатком является то, что в консоли отладки больше не выводятся сведения об исключении. Таким образом, я могу выключить эту точку останова и просмотреть детали и трассировку исключения, но не ГДЕ это произошло, или включить его, чтобы увидеть, где это произошло, но не ПОЧЕМУ. Кто-нибудь знает, как иметь и то, и другое?
Габриэль Дженсен
27

Просто следуйте инструкциям в этом ответе StackOverflow:

Включить зомби

По сути, вам просто нужно «Включить зомби». Тогда Xcode должен сломаться в той строке, которая вызвала проблему.

введите описание изображения здесь

(Абсолютно шокирует то, что даже в 2017 году Xcode по-прежнему отключил это по умолчанию. Почему вы не хотите видеть строку, вызвавшую проблему? И « Включить объекты зомби »?! Действительно?! Неужели авторы Xcode действительно Считаете, что это полезное имя, которое имело бы какой-либо смысл для новых разработчиков? Удручает, насколько низкий рейтинг Xcode из года в год в App Store. Никто не слушает ...)

Майк Гледхилл
источник
6
Xcode - худшая среда программирования, которую я использовал до сих пор.
Студент
Что мне интересно (как разработчик Visual Studio), так это то, сколько разработчиков Xcode я встречал, которые настаивают на том, что Xcode - лучшая среда, которую они когда-либо использовали. Логично, дружелюбно и полезно ... но с некоторыми причудами. Даже сейчас, в ноябре 2019 года, Xcode имеет рейтинг App Store 3,1, при этом большинство людей ставят ему 5 или 1 звезду. Никто не слушает ....
Майк Гледхилл
10

Изменить текущую схему и включить NSZombieEnabled, MallocStackLoggingи guard malloc. Затем, когда ваше приложение выйдет из строя, введите это в консоли gdb:

(gdb) info malloc-history 0x543216

Замените 0x543216адресом объекта, который вызвал NSInvalidArgumentExceptionсбой, и он должен дать вам гораздо более полезную трассировку стека, показывая строки вашего кода, которые вызывают сбой.

Чаун
источник
1
Я попробовал это, и мне выдали ошибку: 'info' не является допустимой командой. Любой совет?
achi
@EliGregory убедитесь, что ваш отладчик установлен на gdb, а не на lldb по умолчанию. Вы можете изменить его в меню «Редактировать схему» в разделе «Выполнить».
chown
2

Я видел такое поведение в сильно оптимизированном коде; проверка, настройка уровня оптимизации вашей цели и сторонних библиотек может помочь. (Настройка уровня оптимизации LLVM 3.0)

Вы генерируете символы отладки?

FluffulousChimp
источник
Согласовано. Если вы пытаетесь отлаживать, тогда уровень оптимизации должен быть установлен на 0 (без оптимизации) в настройках сборки.
Картер
1

Я написал код для генерации сбоя индекса при выходе за пределы. Ниже приведено исключение.

2017-01-07 04:02:57.606 testABC[1694:52966] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010e85cd4b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x000000010e2be21e objc_exception_throw + 48
    2   CoreFoundation                      0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111
    3   testABC                             0x000000010dce962d -[ViewController ComplexFunction] + 61
    4   testABC                             0x000000010dce95db -[ViewController thirdFunction] + 43
    5   testABC                             0x000000010dce959b -[ViewController secondFunction] + 43
    6   testABC                             0x000000010dce955b -[ViewController firstFinction] + 43
    7   testABC                             0x000000010dce96c2 -[ViewController viewDidAppear:] + 50
    8   UIKit                               0x000000010ee28a6c -[UIViewController _setViewAppearState:isAnimating:] + 945
    9   UIKit                               0x000000010ee2b7da __64-[UIViewController viewDidMoveToWindow:shouldAppearOrDisappear:]_block_invoke + 42
    10  UIKit                               0x000000010ee29ac4 -[UIViewController _executeAfterAppearanceBlock] + 86
    11  UIKit                               0x000000010ec8d77c _runAfterCACommitDeferredBlocks + 653
    12  UIKit                               0x000000010ec7a273 _cleanUpAfterCAFlushAndRunDeferredBlocks + 566
    13  UIKit                               0x000000010ec9d757 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke_2 + 194
    14  CoreFoundation                      0x000000010e8016ac __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    15  CoreFoundation                      0x000000010e7e66f4 __CFRunLoopDoBlocks + 356
    16  CoreFoundation                      0x000000010e7e5e65 __CFRunLoopRun + 901
    17  CoreFoundation                      0x000000010e7e5884 CFRunLoopRunSpecific + 420
    18  GraphicsServices                    0x00000001126d9a6f GSEventRunModal + 161
    19  UIKit                               0x000000010ec80c68 UIApplicationMain + 159
    20  testABC                             0x000000010dce99df main + 111
    21  libdyld.dylib                       0x000000011174968d start + 1
    22  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Если вы внимательно прочитаете First Throw call stack

0   CoreFoundation              0x000000010e85cd4b __exceptionPreprocess + 171
1   libobjc.A.dylib             0x000000010e2be21e objc_exception_throw + 48

0 and 1 системные процессы после сбоя.

 2   CoreFoundation             0x000000010e8b5c2f -[__NSSingleObjectArrayI objectAtIndex:] + 111

2 строка, вызвавшая исключение.

3   testABC                     0x000000010dce962d -[ViewController ComplexFunction] + 61

3сообщает вам, что имя класса ( ViewController) и функция naem ( ComplexFunction), в которой было сгенерировано исключение.

AsifHabib
источник
4
Эээ, ладно. Вы абсолютно правы, но это дружелюбно? В любой современной среде разработки (начиная с 1990-х годов) при возникновении исключения происходит переход к строке, вызвавшей проблему. В то время как Xcode ... ну ... дает вам такую ​​трассировку стека. Даже Turbo Pascal не устарел !!!
Майк Гледхилл
4
Смешно, что компания, которая якобы известна своим «лучшим пользовательским интерфейсом», не понимает, что все разработчики за последние 20 лет привыкли видеть номер строки, в которой выбрасывается исключение, а НЕ В СБОРЕНИИ. Я схожу с ума? Каждый язык, с которым я когда-либо работал всю свою жизнь, имеет номера строк. Даже C или C ++.
mylovemhz