Нет исключения трассировки стека в консоли под Xcode 4.2/iOS 5?
В Xcode 3.x и iOS 4, если необработанное исключение сигнализируется в эмуляторе, в выводе консоли создается трассировка стека исключений (похожая на Java).
Когда я вызываю необработанное исключение в iOS 5 под Xcode 4.2, запустив точно такой же код приложения, трассировка стека не происходит. (Я выяснил, как установить точку останова исключения, но это не приводит к трассировке в консоли.)
Это просто настройка XCode, которую мне нужно где-то сделать, или "особенность" XCode 4/iOS 5? Есть ли способ восстановить этот бит функциональности?
Обновить
К сожалению, добавление uncaughtExceptionHandler
не работает Вот обработчик:
void uncaughtExceptionHandler(NSException *exception) {
NSLog(@"uncaughtExceptionHnadler -- Exception %@", [exception description]);
// Because iOS 5 doesn't provide a traceback, provide one here
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
// Let Flurry look at the error
[FlurryAPI logError:@"Uncaught" message:@"Crash!" exception:exception];
}
(Оказывается, он уже присутствовал при создании Flurry, поэтому я просто добавил трассировку стека.)
Вот где он включен (всего несколько строк ниже, где объявлен обработчик):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Enable uncaught exception handler to dump stack and let Flurry log the exception
NSUncaughtExceptionHandler* hdlr = NSGetUncaughtExceptionHandler();
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
NSUncaughtExceptionHandler* newHdlr = NSGetUncaughtExceptionHandler();
// TODO: Test
NSException* ex = [NSException exceptionWithName:@"AssertionFailure" reason:@"Test" userInfo:nil];
@throw ex;
Я установил точки останова, чтобы я мог проверить два полученных значения обработчика. Первый - ноль, а второй - явно действительный адрес. Но когда выдается тестовое исключение, обработчик (в симуляторе iOS 5) никогда не получает управление. (Хотя, когда я запускаю симулятор iOS 4.2, он получает контроль.)
настройка NSExceptionHandlingMask
по-видимому, невозможно на iPhone. Пререк ExceptionHandling.framework
не доступен.
Обновление 2
Это работает:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = -1;
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
[pool release];
return retVal;
}
3 ответа
Это работает:
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = -1;
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
[pool release];
return retVal;
}
Для АРК:
int main(int argc, char *argv[]) {
int retVal = -1;
@autoreleasepool {
@try {
retVal = UIApplicationMain(argc, argv, nil, nil);
}
@catch (NSException* exception) {
NSLog(@"Uncaught exception: %@", exception.description);
NSLog(@"Stack trace: %@", [exception callStackSymbols]);
}
}
return retVal;
}
Все еще жду какого-то объяснения, почему дамп по умолчанию больше не работает и / или почему (даже более серьезный) uncaughtExceptionHandler не работает. Однако, видимо, эта проблема касается только эмулятора.
Обновить:
Было отмечено, что если вы перейдете в Product -> Scheme -> Edit Scheme, выберите "Run (Debug)", выберите вкладку "Diagnostics" и нажмите "Log Exceptions", это восстановит отсутствующую регистрацию исключений Xcode по умолчанию. возможно (я еще не пробовал) устранение необходимости вышеупомянутого взлома.
У меня была та же проблема, возвращение "Compile for Thumb" снова помогло мне. Примечание. Я включил его только для конфигурации отладки по очевидным причинам.