美文网首页
iOS开发-Crash捕捉

iOS开发-Crash捕捉

作者: Henry________ | 来源:发表于2021-06-22 23:08 被阅读0次

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中完成的赋值,代码就不一一呈现了。

相关文章

网友评论

      本文标题:iOS开发-Crash捕捉

      本文链接:https://www.haomeiwen.com/subject/hwkvyltx.html