我尝试使用“PLCrashReport”来收集崩溃信息然后让应用程序更稳定,但事实证明报告是这样的(甚至没有调用堆栈,我想如何使用它?):
“Exception:”部分,例外:(null):( null),应该是“exceptionName”和“exceptionReason”,大多数时候都是“null”,不知道为什么,有时候会有正常值但我觉得不太有用......
于2009-11-13 23:43:04 +0800坠毁 - 信号SIGSEGV(代码SEGV_ACCERR,地址= 0xffffffffc0f4186b)
异常:(null):( null) - 线程0:
答案 0 :(得分:3)
什么是堆栈跟踪?
每当调用一个方法时,它就会将其放入堆栈中。堆栈跟踪是一种查找应用程序崩溃的类和方法的方法,通常会将错误缩小到一行。
当然要做到这一点,堆栈跟踪需要是可读的,而不是整数十六进制数。
查看atos。
为了防止再次发生这种情况,您可以使用atos解释此调用堆栈。 有关如何将这些数字转换为有意义的方法的讨论和代码,请参阅Cocoa Dev wiki的Stack Traces页面。
你需要找到一种方法将其与崩溃记者整合。我使用UKCrashReporter并且我修改了Uli的代码,这样如果有未捕获的异常,它会将可读的堆栈跟踪添加到崩溃报告中。
代码示例
我从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。
答案 1 :(得分:1)
我还没有使用它,但我很确定你没有得到任何细节,因为你有一个分段错误,将所有内容都记录到寄存器中。 PLCrashReport实例无法报告,因为它与其他所有内容一起死亡。
PLCrashReport实例在应用程序本身内运行,因此如果应用程序严重失败,您将无法获得任何详细信息。