Как прочитать журнал сбоев?Как узнать причину сбоя приложения в системной библиотеке?Что означает EXC_CRASH (SIGABRT)?
Вопрос
Я получил журналы сбоев от клиента, чтобы выяснить, почему мое приложение вылетает на ее iPhone.
Вот некоторая информация из журнала сбоев:
Exception Type: EXC_CRASH (SIGABRT) Exception Codes: 0x00000000, 0x00000000 Crashed Thread: 0
Трассировка стека для потока 0
Thread 0 Crashed: 0 libSystem.B.dylib 0x3293f98c 0x328c1000 + 518540 1 libSystem.B.dylib 0x3293f97c 0x328c1000 + 518524 2 libSystem.B.dylib 0x3293f96e 0x328c1000 + 518510 3 libSystem.B.dylib 0x3295461a 0x328c1000 + 603674 4 libstdc++.6.dylib 0x30a143b0 0x309cf000 + 283568 5 libobjc.A.dylib 0x3347a858 0x33475000 + 22616 6 libstdc++.6.dylib 0x30a12776 0x309cf000 + 276342 7 libstdc++.6.dylib 0x30a127ca 0x309cf000 + 276426 8 libstdc++.6.dylib 0x30a12896 0x309cf000 + 276630 9 libobjc.A.dylib 0x33479714 0x33475000 + 18196 10 CoreFoundation 0x335c8210 0x33534000 + 606736 11 CoreFoundation 0x3354ea8e 0x33534000 + 109198 12 CoreFoundation 0x33545ab8 0x33534000 + 72376 13 Journaler Lite 0x0001699e -[AccountManager unsignedIntegerValueForPath:] (AccountManager.m:151) ...
Вот код из AccountManager.m
:
NSNumber *number = ...; if (number) { return [number unsignedIntegerValue]; // line 151 } else { return 0; }
Главный вопрос: как читать такой журнал сбоев?Приложение вылетает где-то внутри системной библиотеки, дополнительной информации больше нет.Есть ли способ найти причину сбоя?
обновлять:Я прогуглил много сообщений на форумах, где тип исключения: EXC_CRASH (SIGABRT)
и первые строки из разбившегося стека потоков:
Thread 0 Crashed: 0 libSystem.B.dylib 0x3293f98c 0x328c1000 + 518540 1 libSystem.B.dylib 0x3293f97c 0x328c1000 + 518524 2 libSystem.B.dylib 0x3293f96e 0x328c1000 + 518510 3 libSystem.B.dylib 0x3295461a 0x328c1000 + 603674 4 libstdc++.6.dylib 0x30a143b0 0x309cf000 + 283568 5 libobjc.A.dylib 0x3347a858 0x33475000 + 22616 6 libstdc++.6.dylib 0x30a12776 0x309cf000 + 276342 7 libstdc++.6.dylib 0x30a127ca 0x309cf000 + 276426 8 libstdc++.6.dylib 0x30a12896 0x309cf000 + 276630 9 libobjc.A.dylib 0x33479714 0x33475000 + 18196 10 CoreFoundation 0x335c8210 0x33534000 + 606736 11 CoreFoundation 0x3354ea8e 0x33534000 + 109198
Что означает этот тип исключения (EXC_CRASH (SIGABRT)
) иметь в виду?
Решение
Во-первых, вам нужно обозначить журнал сбоев с помощью DSYM, чтобы понять, что происходит.Вам понадобится файл DSYM с момента создания приложения.Файл DSYM позволяет вам преобразовать эти адреса памяти обратно в читаемые строки кода.
SIGABRT — это сигнал, который вы получаете при возникновении необработанного исключения, например при вызове [someArray objectAtIndex:2]
если бы в массиве был только 1 элемент.Или, что чаще, нераспознанный селектор: [NSArray unsignedIntValue]
.
Взгляните на этот журнал сбоев. этот вопрос.Обратите внимание, что библиотеки стека вызовов в Foundation такие же, как и ваш код, и это нераспознанный селектор.
Ваш код:
NSNumber *num = foo;
if (num)
{
bar = [num unsignedIntValue];
}
То, что вы нам не сказали — но это очень важно — это то, что находится в «foo».Как вы назначаете этот NSNumber?Если это любой другой объект, кроме NSNumber, ваш журнал сбоев будет выглядеть так же, как ваш.
Если вы хотите ДЕЙСТВИТЕЛЬНО защищаться в своем программировании, вы можете сказать:
if (num && [num isKindOfClass:[NSNumber class]])
Но на самом деле, каким бы ни было ваше «foo», оно всегда должно возвращать NSNumber.