Ничто из того, что я пробовал, не исправило бы это (пробовал оба компилятора, оба отладчика и т. Д.). После обновления XCode для обновления iOS 5 никакие трассировки стека, похоже, не работали.
Однако я нашел эффективный обходной путь - создал собственный обработчик исключений (который также полезен по другим причинам). Сначала создайте функцию, которая будет обрабатывать ошибку и выводить ее на консоль (а также все, что вы хотите с ней делать):
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"CRASH: %@", exception);
NSLog(@"Stack Trace: %@", [exception callStackSymbols]);
}
Затем добавьте обработчик исключений в делегат вашего приложения:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
}
Это оно!
Если это не сработает, то есть только две возможные причины :
- Что-то перезаписывает ваш
NSSetUncaughtExceptionHandler
вызов (для всего приложения может быть только один обработчик). Например, некоторые сторонние библиотеки устанавливают собственный uncaughtExceptionHandler. Итак, попробуйте установить его в КОНЕЦ вашей didFinishLaunchingWithOptions
функции (или выборочно отключите сторонние библиотеки). Или еще лучше, установите символическую точку останова, NSSetUncaughtExceptionHandler
чтобы быстро увидеть, кто звонит. Что вы можете сделать, так это изменить текущий, а не добавлять еще один.
- На самом деле вы не сталкиваетесь с исключением (например,
EXC_BAD_ACCESS
это не исключение; кредит на комментарии @Erik B ниже)
uncaughtExceptionHandler
процедура никогда не запускается.Существует полезная опция добавления точки останова на исключение (используя + в нижней части навигатора точек останова). Это нарушит любое исключение (или вы можете установить условия). Я не знаю, является ли этот выбор новым в версии 4.2 или я только что заметил, что он пытается решить проблему с отсутствующими символами.
Как только вы нажмете эту точку останова, вы можете использовать Debug Navigator для навигации по стеку вызовов, проверки переменных и т.д. как обычно.
Если вам нужен символьный стек вызовов, подходящий для копирования / вставки или чего-то подобного, gdb backtrace будет работать нормально оттуда:
(gdb) bt #0 0x01f84cf0 in objc_exception_throw () #1 0x019efced in -[NSObject doesNotRecognizeSelector:] ()
(так далее)
источник
В отладчике есть новая функция. Вы можете установить точку останова всякий раз, когда возникает исключение, и сразу же останавливать выполнение, как это было раньше в 4.0.
В «Навигаторе точек останова» добавьте «Исключительную точку останова» и просто нажмите «Готово» во всплывающем окне с параметрами.
Вот и все!
PS: В некоторых случаях было бы лучше сломать только исключения Objective-C.
источник
Вот еще одно решение, не такое элегантное, как предыдущее, но если вы не добавляли точки останова или обработчики исключений, это может быть только один путь.
Когда приложение вылетает из строя и вы получаете необработанный стек вызовов первого вызова (в шестнадцатеричном формате), введите в консоль Xcode
info line *hex
(не забывайте звездочку и0x
шестнадцатеричный спецификатор), например:(gdb) info line *0x2658 Line 15 of "path/to/file/main.m" starts at address 0x25f2 <main+50> and ends at 0x267e <main+190>.
Если вы используете lldb , вы можете ввести
image lookup -a hex
(без звездочки в этой ситуации), и вы получите аналогичный результат.С помощью этого метода вы можете перейти от вершины стека выброса (будет около 5-7 распространителей системных исключений) к вашей функции, вызвавшей сбой, и определить точный файл и строку кода.
Кроме того, для аналогичного эффекта вы можете использовать утилиту atos в терминале, просто введите:
atos -o path/to/AplicationBundle.app/Executable 0xAdress1 0xAdress2 0xAdress3 ...
и вы получите символьную трассировку стека (по крайней мере, для функций, у которых есть символы отладки). Этот метод более предпочтителен, потому что у вас нет для каждого вызова адреса
info line
, просто скопируйте адреса из вывода консоли и вставьте их в терминал.источник
Вы можете добавить точку останова при исключении (используя + в нижней части навигатора точек останова) и добавить
bt
к ней действие (нажмите кнопку «Добавить действие», выберите «Команда отладчика», введите «bt» в текстовое поле). Это отобразит трассировку стека, как только возникнет исключение.источник
Это обычная проблема - отсутствие трассировки стека в 4.2. Вы можете попробовать переключаться между LLDB и GDB, чтобы увидеть, получите ли вы лучшие результаты.
Отправьте отчет об ошибке здесь.
http://developer.apple.com/bugreporter/
РЕДАКТИРОВАТЬ:
Я считаю, что если вы вернетесь к LLVM GCC 4.2, вы этого не увидите. Однако вы можете потерять нужные вам функции.
источник
Используйте этот код в своей основной функции:
int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int retVal; @try { retVal = UIApplicationMain(argc, argv, nil, nil); } @catch (NSException *exception) { NSLog(@"CRASH: %@", exception); NSLog(@"Stack Trace: %@", [exception callStackSymbols]); } @finally { [pool release]; } return retVal; }
источник
В командной строке консоли отладки Xcode введите:
И он покажет вам что-то вроде:
Address: MyApp[0x00018eb0] (MyApp.__TEXT.__text + 91088) Summary: MyApp`-[MyViewController viewDidAppear:] + 192 at MyViewController.m:202
источник
У меня сработало включение «Компилировать для большого пальца» (конфигурация отладки).
источник