Xcode не показывает строку, которая вызывает сбой
Каждый раз, когда мое приложение падает, 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 точно знает, что вызвало крах (или может знать), но пока не показывает фактическую строку. Есть ли какое-либо исправление или обходное решение для этого?
Ответы
Ответ 1
Вы также должны убедиться, что у вас есть контрольные точки, установленные для всех исключений. Это приведет к остановке Xcode в строке, где происходит исключение. Сделайте следующее [в Xcode 4]:
-
В Навигаторе проектов с левой стороны Xcode нажмите на навигатор точки останова (почти весь путь до правой стороны верхней панели кнопок). Значок выглядит как жирная стрелка вправо.
-
В нижней части навигатора нажмите кнопку "+".
-
Нажмите "Добавить точку останова исключения".
-
Будет создана новая точка останова. Он должен быть настроен по мере необходимости, но вы можете настроить его поведение.
-
Запустите проект и воспроизведите исключение.
Также вы упомянули, что вы связаны с некоторыми сторонними библиотеками/фреймами. Если исключение происходит в этих рамках, вам будет сложно скомпилировать код, и Xcode не сможет показать вам строку, вызвавшую исключение. Если это так, и вы уверены, что используете библиотеки правильно, вы должны отправить отчет об ошибках сторонним разработчикам этих библиотек.
Ответ 2
Просто следуйте инструкциям в этом ответе StackOverflow:
Включить зомби
В принципе, вам просто нужно "Включить зомби". Затем Xcode должен ломаться в зависимости от того, какая строка вызвала проблему.
![введите описание изображения здесь]()
(Совершенно шокирует то, что даже в 2017 году Xcode по-прежнему отключен по умолчанию. Почему бы вам не захотеть увидеть строку, вызвавшую проблему? И "Включить объекты зомби"? Действительно? Авторы Xcode действительно считают, что это полезное имя, которое будет иметь какой-то смысл для новых разработчиков? Удручает, как плохой рейтинг Xcode год за годом в App Store. Никто не слушает...)
Ответ 3
Отредактируйте текущую схему и включите NSZombieEnabled
, MallocStackLogging
и guard malloc
. Затем, когда ваше приложение выйдет из строя, введите его в консоли gdb:
(gdb) info malloc-history 0x543216
Замените 0x543216
адресом объекта, который вызвал NSInvalidArgumentException
, и он должен дать вам гораздо более полезную трассировку стека, отображающую строки вашего кода, вызывающие сбой.
Ответ 4
Я видел это поведение в сильно оптимизированном коде; проверка, настройка уровня вашей целевой оптимизации и поддержки сторонних библиотек. (Настройка уровня LLVM 3.0)
Вы генерируете символы отладки?
Ответ 5
Я написал код для генерации сбоя индекса из привязки.
Ниже приведено исключение.
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
), в котором было выбрано исключение.