iOS开发-Crash捕捉

1、手动捕捉crash

即使有了bugly,也需要知道奔溃是如何捕捉的。
注意:自定义NSSetUncaughtExceptionHandler之后,会导致bugly失效,需要注意!!

void UncaughtExceptionHandler(NSException *exception) {
    NSArray *arr = [exception callStackSymbols];
    NSString *reason = [exception reason];
    NSString *name = [exception name];
    NSLog(@"\n%@\n%@\n%@",arr,reason,name);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        //在可能发生奔溃之前就需要完成注册
        NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
}
  • 可以将奔溃收集起来后上传服务器。

2、自定义NSException

 //创建异常
    NSString *exceptionName = @"hi,我是一个异常";
    NSString *excaptionReason = @"我不开心了,所以我要让程序崩溃";
    NSDictionary *exceptionUserInfo = nil;
    NSException *exception = [NSException exceptionWithName:exceptionName reason:excaptionReason userInfo:exceptionUserInfo];
    
    //抛出异常
    @throw exception;
  • 当然NSException的强大并没有完全展示出来。

3、系统是如何触发自定义奔溃

3.1 在_objc_init中完成exception初始化

  //runtime的初始化函数
void _objc_init(void)
{
    ...
    //crash奔溃的处理
    exception_init();
}

void exception_init(void)
{
    //  _objc_terminate是一个函数指针 
    old_terminate = std::set_terminate(&_objc_terminate);
}

//系统出现crash都会来到这个函数
static void _objc_terminate(void)
{
    if (! __cxa_current_exception_type()) {
        // No current exception.
        (*old_terminate)();
    }
    else {
        // There is a current exception. Check if it's an objc exception.
        @try {
            __cxa_rethrow();
        } @catch (id e) {
            //系统奔溃之后会调用这个uncaught_handler指针函数
            (*uncaught_handler)((id)e);
             (*old_terminate)();
        } @catch (...) {
            // It's not an objc object. Continue to C++ terminate.
            (*old_terminate)();
        }
    }
}

3.2 uncaught_handler

// uncaught_handler 的默认值,什么处理都不做
static void _objc_default_uncaught_exception_handler(id exception)
{}

static objc_uncaught_exception_handler uncaught_handler = _objc_default_uncaught_exception_handler;
  • uncaught_handler是一个函数指针。

3.3 objc_setUncaughtExceptionHandler

//通过该函数完成uncaught_handler的自定义赋值
objc_uncaught_exception_handler
objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler fn)
{
    ...
    uncaught_handler = fn;

    return result;
}
  • uncaught_handler的指针指向了自定义的方法,也就是文章最开始的UncaughtExceptionHandler函数;等待_objc_terminate的函数调用。

3.4 NSSetUncaughtExceptionHandler和objc_setUncaughtExceptionHandler关系

函数NSSetUncaughtExceptionHandler是基于CoreFounation的上层封装,底层是objc_setUncaughtExceptionHandler这个函数。

  • callUncaughtHandler是NSSetUncaughtExceptionHandler中完成的赋值,代码就不一一呈现了。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容