前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS开发-Crash捕捉iOS开发-Crash捕捉

iOS开发-Crash捕捉iOS开发-Crash捕捉

作者头像
用户8893176
发布2021-08-09 11:20:40
2.5K0
发布2021-08-09 11:20:40
举报
文章被收录于专栏:小黑娃Henry

1、手动捕捉crash

即使有了bugly,也需要知道奔溃是如何捕捉的。

注意:自定义NSSetUncaughtExceptionHandler之后,会导致bugly失效,需要注意!!

代码语言:javascript
复制
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

代码语言:javascript
复制
 //创建异常
    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初始化
代码语言:javascript
复制
  //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
代码语言:javascript
复制
// 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
代码语言:javascript
复制
//通过该函数完成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中完成的赋值,代码就不一一呈现了。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/6/22 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、手动捕捉crash
  • 2、自定义NSException
  • 3、系统是如何触发自定义奔溃
    • 3.1 在_objc_init中完成exception初始化
      • 3.2 uncaught_handler
        • 3.3 objc_setUncaughtExceptionHandler
          • 3.4 NSSetUncaughtExceptionHandler和objc_setUncaughtExceptionHandler关系
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档