Подтвердить что ты не робот

Как получить строку исходного кода из трассировки стека в obj-c/ios

Я использую NSSetUncaughtExceptionHandler для печати трассировки стека в локальный файл на iPhone, который будет отправлен на наш сервер в следующий раз, когда приложение запустится. Затем я могу проверить данные исключения и исправить ошибку. В некоторых авариях у меня есть имя модуля и функция, которая выбрала исключение, это легко. Но в основном у меня есть что-то вроде этого:

"4   libc++abi.dylib 0x35bba3c5 _ZL19safe_handler_callerPFvvE + 76",
"5   libc++abi.dylib 0x35bba451 _ZdlPv + 0",
"6   libc++abi.dylib 0x35bbb825 __cxa_current_exception_type + 0",
"7   libobjc.A.dylib 0x37bab2a9 objc_exception_rethrow + 12",
"8   CoreFoundation  0x3575a50d CFRunLoopRunSpecific + 404"

и, например, причина:

*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array

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

Кто-нибудь знает хорошую статью/учебник от Apple или другой, где я могу научиться декодировать числа в трассировке стека, чтобы найти проблемную строку в исходном коде. Спасибо заранее!

4b9b3361

Ответ 1

Я настоятельно рекомендую включить исключение Breakpoint в Xcode. Он прекратит выполнение вашего кода на точной строке, которая приведет к сбою вашего приложения. Поэтому вам не нужно беспокоиться о том, какая из причин массива аварии. *** - [__ NSArrayI objectAtIndex:]: индекс 0 за пределами для пустого массива

Добавление контрольной точки исключения

  • Перейдите в раздел "Точки останова" на Xcode
  • Нажмите "плюс" в нижней части раздела.
  • Выберите пункт "Добавить контрольную точку исключения"

Exception BreakPoint

Ответ 2

Я не знаю, как получить номера строк из трассировки стека (пока), но в некоторых точках моего кода, где я хочу напечатать номер строки, я использовал следующий фрагмент кода:

NSLog(@"%s line=%d", __func__, __LINE__);

который даст следующий результат:

2013-04-01 00:16:46.393 MyApp[847:c07] -[AppDelegate application:didFinishLaunchingWithOptions:] line=29

Если вы знакомы с базой Log4J, я предлагаю взглянуть на структуру Lumberjack, которая оказывается очень полезной для меня в различных проектах.

https://github.com/robbiehanson/CocoaLumberjack

Хотя это не может напрямую ответить на ваш вопрос, это просто означает напоминание.

Ответ 3

Установите точку останова в блоке catch, как только поток кода остановится, вы можете использовать команды gdb, такие как 'bt'.

Ответ 4

Распечатайте трассировку стека, хранящуюся в исключении, т.е. [exception callStackSymbols] или [exception callStackReturnAddresses]. В журналах сбоев Apple с iOS 5 это отображается вверху как "Last Exception Backtrace".

То, что вы видите, это стек вызовов, когда исключение повторно выбрано, что будет происходить так же просто, как try...finally. Я точно не знаю, почему Apple сделала это изменение (возможно, чтобы избежать ошибок в циклах цикла), но там вы идете.