有些低概率很难重现的闪退会让程序员很头疼,不知道怎么定位问题,其实是有办法捕获崩溃并获得当时的调用堆栈的。拿到堆栈保存下来,找个合适的时机回传到服务器给se分析,可以大大提高修复闪退的工作效率。
首先定义一个捕获异常的NSUncaughtExceptionHandler
void exceptionHandler(NSException *exception) {
NSLog(@"exit with exception: %@", [exception reason]); // reason为崩溃原因描述
NSLog(@"%@", [exception callStackSymbols]); // 这个方法可以难道崩溃时的调用堆栈
}
在启动的时候设置未捕获异常的处理函数
NSSetUncaughtExceptionHandler(&exceptionHandler);
==============================
以上是obj-c层面的,如果需要处理c层面的,可参考如下代码
定义要捕获的信号
static int s_fatal_signals[] = {
SIGABRT,
SIGBUS,
SIGFPE,
SIGILL,
SIGSEGV,
SIGTRAP,
SIGTERM,
SIGKILL,
};
信号的名称
static const char* s_fatal_signal_names[] = {
"SIGABRT",
"SIGBUS",
"SIGFPE",
"SIGILL",
"SIGSEGV",
"SIGTRAP",
"SIGTERM",
"SIGKILL",
};
static int s_fatal_signal_num = sizeof(s_fatal_signals) / sizeof(s_fatal_signals[0]);
获取调用堆栈的函数
+ (NSArray *)backtrace {
void *callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack, frames);
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (int i = 0; i < frames; ++i) {
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs);
return backtrace;
}
信号处理函数
void signalHandler(int signal) {
for (int i = 0; i < s_fatal_signal_num; ++i) {
if (signal == s_fatal_signals[i]) {
NSLog(@"exit with signal: %s", s_fatal_signal_names[i]);
NSLog(@"%@", [AppDelegate backtrace]);
break;
}
}
}
注册捕获信号的方法,启动的时候调用
void InitCrashReport() {
// linux错误信号捕获
for (int i = 0; i < s_fatal_signal_num; ++i) {
signal(s_fatal_signals[i], signalHandler);
}
}
首先定义一个捕获异常的NSUncaughtExceptionHandler
void exceptionHandler(NSException *exception) {
NSLog(@"exit with exception: %@", [exception reason]); // reason为崩溃原因描述
NSLog(@"%@", [exception callStackSymbols]); // 这个方法可以难道崩溃时的调用堆栈
}
在启动的时候设置未捕获异常的处理函数
NSSetUncaughtExceptionHandler(&exceptionHandler);
==============================
以上是obj-c层面的,如果需要处理c层面的,可参考如下代码
定义要捕获的信号
static int s_fatal_signals[] = {
SIGABRT,
SIGBUS,
SIGFPE,
SIGILL,
SIGSEGV,
SIGTRAP,
SIGTERM,
SIGKILL,
};
信号的名称
static const char* s_fatal_signal_names[] = {
"SIGABRT",
"SIGBUS",
"SIGFPE",
"SIGILL",
"SIGSEGV",
"SIGTRAP",
"SIGTERM",
"SIGKILL",
};
static int s_fatal_signal_num = sizeof(s_fatal_signals) / sizeof(s_fatal_signals[0]);
获取调用堆栈的函数
+ (NSArray *)backtrace {
void *callstack[128];
int frames = backtrace(callstack, 128);
char **strs = backtrace_symbols(callstack, frames);
NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
for (int i = 0; i < frames; ++i) {
[backtrace addObject:[NSString stringWithUTF8String:strs[i]]];
}
free(strs);
return backtrace;
}
信号处理函数
void signalHandler(int signal) {
for (int i = 0; i < s_fatal_signal_num; ++i) {
if (signal == s_fatal_signals[i]) {
NSLog(@"exit with signal: %s", s_fatal_signal_names[i]);
NSLog(@"%@", [AppDelegate backtrace]);
break;
}
}
}
注册捕获信号的方法,启动的时候调用
void InitCrashReport() {
// linux错误信号捕获
for (int i = 0; i < s_fatal_signal_num; ++i) {
signal(s_fatal_signals[i], signalHandler);
}
}