iOS开发~Crash优化

本文详述了iOS应用开发中Crash的原因、类型、捕获方法及日志获取,包括异常和信号错误的处理,重点讨论了EXC_BAD_ACCESS错误的调试,以及如何通过崩溃日志进行符号化分析,以优化和解决App的Crash问题。
摘要由CSDN通过智能技术生成

一、概要

iOS App开发中和上线后,都会遇到程序异常退出的情况,导致崩溃的原因有很多,如果是在调试的过程中,可以通过设施断点或者打印关键信息的方式来进行调试,如果对于一些复杂模块非必现的异常崩溃,这种方式有时难以定位问题,而且对于已经发布上线的应用,这种方式更是无能为力。下面详细讨论崩溃产生的原因以及如何处理。

 

二、Crash的捕获

1、Crash产生原因

1、应用中有Bug。 2、Watchdog 超时机制 3、用户强制退出 4、低内存终止 5、其他违反系统规则的操作,大部分是内存问题 发生崩溃,系统会生成一份崩溃日志在本地,或者上传 ITC

 

2、Crash的类型(异常、信号错误)

通常我们见到的Crash分为两种,异常和信号错误。

异常:系统内存错误,触发EXC_BAD_ACCESS引起的,程序运行过程中访问了错误的内存地址。

NSRangeException等 NSException类

信号错误:出现了不能被处理的signal异常,导致程序向自身发送了SIGABRT信号而崩溃。

信号中断(SGIABRT)、非法指令信号(SIGILL)、总线错误信号(SIGBUS)、段错误信号(SIGSEGV)、访问一个已经释放的对象(EXC_BAD_ACCESS)

3、捕获异常崩溃信息

只能捕获一些异常崩溃,如 unrecognized selector、NSRangeException beyond bounds越界等Exception属错误

Appdelegate

在Appdelegate 的 didFinishLaunchingWithOptions 中 添加
NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);

方法实现如下
void UncaughtExceptionHandler(NSException *exception) {
    /**
     *  获取异常崩溃信息
     */
    NSArray *callStack = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSString *name = [exception name];
    NSString *content = [NSString stringWithFormat:@"========异常错误报告========\nname:%@\nreason:\n%@\ncallStackSymbols:\n%@",name,reason,[callStack componentsJoinedByString:@"\n"]];
    
    //将崩溃信息持久化在本地,下次程序启动时、或者后台,将崩溃信息作为日志发送给开发者。
    [[NSUserDefaults standardUserDefaults] setObject:content forKey:@"ExceptionContent"];
}

测试

数组越界错误 NSMutableArray *array = [NSMutableArray array]; NSLog(@"%@",array[1]);

4、捕获信号错误崩溃信息

信号类型崩溃捕获,测试的时候如果测试Signal类型的崩溃,不要在xcode下的debug模式进行测试。因为系统的debug会优先去拦截。应该build好应用之后直接点击运行app进行测试。

什么是信号

在计算机科学中,信号(英语:Signals)是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。


在iOS中就是未被捕获的Objective-C异常(NSException),导致程序向自身发送了SIGABRT信号而崩溃。

SIGABRT–程序中止命令中止信号
SIGALRM–程序超时信号
SIGFPE–程序浮点异常信号
SIGILL–程序非法指令信号
SIGHUP–程序终端中止信号
SIGINT–程序键盘中断信号
SIGKILL–程序结束接收中止信号
SIGTERM–程序kill中止信号
SIGSTOP–程序键盘中止信号
SIGSEGV–程序无效内存中止信号
SIGBUS–程序内存字节未对齐中止信号
SIGPIPE–程序Socket发送失败中止信号

捕获方法

Appdelegate 的 didFinishLaunchingWithOptions 中 添加

signal(SIGHUP, SignalHandler);
signal(SIGINT, SignalHandler);
signal(SIGQUIT, SignalHandler);

signal(SIGABRT, SignalHandler);
signal(SIGILL, SignalHandler);
signal(SIGSEGV, SignalHandler);
signal(SIGFPE, SignalHandler);
signal(SIGBUS, SignalHandler);
signal(SIGPIPE, SignalHandler);

方法实现如下

void SignalHandler(int signal){
    
    int32_t exceptionCount = OSAtomicIncrement32(&UncaughtExceptionCount);
    if (exceptionCount > UncaughtExceptionMaximum)
    {
        return;
    }
    
    void* callstack[128];
    int frames = backtrace(callstack, 128);
    char **strs = backtrace_symbols(callstack, frames);
    
    int i;
    NSMutableArray *backtrace = [NSMutableArray arrayWithCapacity:frames];
    for (
         i &#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zfpp25_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值