Что такое трассировка стека?
Каждый раз, когда вызывается один из ваших методов, он помещает это в стек. Трассировка стека - это способ выяснить, в каком классе и методе произошло сбой вашего приложения, что часто сводит ошибку к одной строке.
Конечно, для этого трассировка стека должна быть читаемой, а не целая загрузка шестнадцатеричных чисел.
Выезд на ато.
Чтобы это не повторилось, вы можете интерпретировать этот стек вызовов с помощью atos.
См. Страницу Stack Traces вики Cocoa Dev для обсуждения и кода о том, как преобразовать эти числа в значимые методы.
Вам нужно будет найти способ интегрировать это с репортером сбоев. Я использую UKCrashReporter, и я изменил код Ули, так что если есть необработанное исключение, он добавляет читаемую трассировку стека в отчет о сбое.
Пример кода
Я черпал вдохновение из класса ESStackTrace и вот что я делаю:
-(void)logAndSaveStackTrace {
NSString *stackTrace = [[self userInfo] objectForKey:NSStackTraceKey];
NSString *atosCommand;
if (stackTrace) {
// If the stack trace key is present, pull out the addresses and convert to method names using atos.
atosCommand = [NSString stringWithFormat:@"/usr/bin/atos -p %d %@ | tail -n +3 | head -n +%d | c++filt | cat -n",
[[NSProcessInfo processInfo] processIdentifier],
stackTrace,
([[stackTrace componentsSeparatedByString:@" "] count] - 4)];
} else {
// If there isn't a stack trace key or it's nil, try and work out the stack using the internal callStackReturn addresses method.
NSArray *stackTraceArray = [self callStackReturnAddresses];
atosCommand = [NSString stringWithFormat:@"/usr/bin/atos -p %d %@",
[[NSProcessInfo processInfo] processIdentifier],
[stackTraceArray componentsJoinedByString:@" "]];
}
NSString *readableStackTrace = [ShellTask executeShellCommandSynchronously:atosCommand];
NSString *exceptionMessageForCrashReport = [NSString stringWithFormat:@"An exception of type %s occured.\n%s\nStack trace:\n%@",
[[self name] cStringUsingEncoding:NSUTF8StringEncoding],
[[self reason] cStringUsingEncoding:NSUTF8StringEncoding],
readableStackTrace];
[[NSUserDefaults standardUserDefaults] setObject:exceptionMessageForCrashReport forKey:@"uncaughtExceptionReport"];
[[NSUserDefaults standardUserDefaults] synchronize];
// Log the exception to the console too.
NSLog(@"%@", exceptionMessageForCrashReport);
}
Зависимости Ахой!
Конечно, одна из проблем этого подхода заключается в том, что вы вводите зависимость от atos. Мне сказали, что он установлен как стандарт на 10.5 и позже, но это может быть неправильно. В конце концов я собираюсь сделать небольшой установщик, который добавляет atos, если мое приложение не может его найти.