版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jingcheng345413/article/details/71056034
一、概述
iOS-App崩溃分为两种,一种是异常:NSException,一种是信号:Signal。
二、异常崩溃
1.NSException对象
(1)reason:崩溃原因。
(2)callStackSymbols:调用堆栈。
(3)name:崩溃名称
(4)userInfo:崩溃对象。
2.崩溃拦截:
(1)声明异常拦截方法
(1)NSSetUncaughtExceptionHandler只维护一个拦截方法,如果在一个App内,有多处设置了拦截方法,则只有最后一个拦截方法生效,所以需要做到拦截衔接。
(2)设置拦截器方法之前,先获取上一个拦截方法
三、信号崩溃
1.设置拦截,并保存上一个设置的拦截方法
2.拦截方法
3.调用上一个设置的拦截方法
iOS-App崩溃分为两种,一种是异常:NSException,一种是信号:Signal。
二、异常崩溃
1.NSException对象
(1)reason:崩溃原因。
(2)callStackSymbols:调用堆栈。
(3)name:崩溃名称
(4)userInfo:崩溃对象。
2.崩溃拦截:
(1)声明异常拦截方法
static void uncaughtExceptionHandler(NSException *exception){}
(2)设置拦截方法
NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
3.崩溃拦截衔接
(2)设置拦截器方法之前,先获取上一个拦截方法
NSUncaughtExceptionHandler *lastExceptionHandler = NSGetUncaughtExceptionHandler();
(3)在自己的拦截方法中,调用上一个拦截方法
lastExceptionHandler(exception);
三、信号崩溃
1.设置拦截,并保存上一个设置的拦截方法
//旧的信号处理函数结构体
static struct sigaction oldSigAction_SIGSYS;
static struct sigaction oldSigAction_SIGSEGV;
//初始化处理函数结构体
struct sigaction newSigAction;
newSigAction.sa_handler = signalHandler;
//在该信号处理函数运行时,内核将不会阻塞该信号、将信号的处理函数重置为缺省值
newSigAction.sa_flags = SA_RESETHAND | SA_NODEFER;
//本进程收到SIGQUIT信号,将阻塞该信号,直到signalHandler执行结束才会处理信号SIGQUIT
sigaddset(&newSigAction.sa_mask, SIGQUIT);
//添加信号和处理函数的关系,并保存旧的信号处理函数
sigaction(SIGSYS, &newSigAction, &oldSigAction_SIGSYS);
sigaction(SIGSEGV, &newSigAction, &oldSigAction_SIGSEGV);
2.拦截方法
static void signalHandler(int signal)
{
//合成堆栈信息
void *frames[128];
int i, len = backtrace(frames, 128);
char **symbols = backtrace_symbols(frames, len);
NSMutableString *exceptionContent = [[NSMutableString alloc] initWithCapacity:4096];
for (i = 0; i < len; ++i)
{
[exceptionContent appendFormat:@"%s\r\n", symbols[i]];
}
//释放缓存
free(symbols)
//调用上一个设置的拦截方法,见3。
}
3.调用上一个设置的拦截方法
switch (signal)
{
case SIGSEGV:
{
if (oldSigAction_SIGSEGV.sa_handler != nil)
{
oldSigAction_SIGSEGV.sa_handler(signal);
}
break;
}
case SIGSYS:
{
if (oldSigAction_SIGSYS.sa_handler != nil)
{
oldSigAction_SIGSYS.sa_handler(signal);
}
break;
}
}