美文网首页iOS精选
iOS监听signal捕捉崩溃

iOS监听signal捕捉崩溃

作者: Stroman | 来源:发表于2018-09-12 17:34 被阅读541次

    总述

    网上不少文章几乎都是你抄我我抄你的,结果要么没一个有用的,要么就太复杂,写文章是给人看的呀,要写得简单通俗啊!于是我干脆自己写一个博客,来简单地说明一下如何通过监听signal来捕获crash。

    捕获异常

    这个可以通过NSSetUncaughtExceptionHandler并搭配处理异常用的处理函数来使用。

    NSSetUncaughtExceptionHandler(&HandleException);
    

    其中HandleException和NSSetUncaughtExceptionHandler都是C语言形式的函数。

    捕获signal

    这个其实很简单,在崩溃的时候iOS会发出signal,你只需要捕获这个signal并搭配以相应的处理句柄即可做相应的处理。
    具体如下:

    signal(SIGABRT, handleSignal);
    

    其中signal和handleSignal都是C语言函数,SIGABRT是个宏。
    handleSignal就是相应处理的那个句柄了。

    完整的组合

    因为这些都是C语言函数,所以都是按照C语言的语法来写,不过没关系,你依然可以写在OC的源文件中,只不过把OC的源文件当做一个载体来使用罢了。下面这个是头文件.h代码。

    #import <Foundation/Foundation.h>  
    @interface CrashExceptionHandler : NSObject 
    @end  
    void RegisterSignalHandler(void);
    

    实现文件.m代码

    #import "CrashExceptionHandler.h"  
    void HandleException(NSException *exception); 
    void handleSignal(int signo);  
    @implementation CrashExceptionHandler 
    @end  
    void HandleException(NSException *exception) {     
    printf("这是在处理异常\n");     
    [[NSNotificationCenter defaultCenter] postNotificationName:@"hello" object:nil]; 
    }  
    void handleSignal(int signo) {     
    printf("这是在处理信号\n");     
    [[NSNotificationCenter defaultCenter] postNotificationName:@"hello" object:nil]; 
    }  
    void RegisterSignalHandler(void) {     
    NSSetUncaughtExceptionHandler(&HandleException);     
    //注册程序由于abort()函数调用发生的程序中止信号     
    signal(SIGABRT, handleSignal);     
    //注册程序由于非法指令产生的程序中止信号     
    signal(SIGILL, handleSignal);     
    //注册程序由于无效内存的引用导致的程序中止信号     
    signal(SIGSEGV, handleSignal);     
    //注册程序由于浮点数异常导致的程序中止信号     
    signal(SIGFPE, handleSignal);     
    //注册程序由于内存地址未对齐导致的程序中止信号     
    signal(SIGBUS, handleSignal);     
    //程序通过端口发送消息失败导致的程序中止信号     
    signal(SIGPIPE, handleSignal); 
    }
    

    如何使用?

    你需要在AppDelegate.m中,像下面这样使用

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {     
    // Override point for customization after application launch.     
    RegisterSignalHandler();     
    return YES;
     }
    

    注意

    在debug模式下,如果你触发了崩溃,那么应用会直接崩溃到主函数,断点都没用,此时没有任何log信息显示出来,如果你想看log信息的话,你需要在lldb中,拿SIGABRT来说吧,敲入pro hand -p true -s false SIGABRT命令,不然你啥也看不到。

    1. 在工程中设置一个断点,以便能够使用调试命令。


      1.png
    2. 运行工程选择第一个选项——SIGABRT,运行到断点的时候在控制台输入"注意"我写的那个命令。


      2.png
    3. 跳过断点继续运行就可以看到结果了。


      3.png

    源代码

    这是用Objective-C编写的,运行于iOS平台的,用XCode跑的,不要搞错了。进入APP是紫色的启动页面,再进去是一个列表,每个单元格都会触发一个崩溃。运行之前现在viewDidLoad里面设个断点,然后输入我在"注意"中写的命令,就可以在崩溃之前看到相应的log输出了。好了,大致的内容就说到这里了,详细地就自己看demo吧,很简单哒,干扰因素忒少。点此下载

    多谢捧场

    如果您觉得我的文章有价值,那么赏脸打赏一个,鄙人感激不尽。不过,不打赏看看也是好的,如果有不对的地方,还请您多多指正。


    相关文章

      网友评论

        本文标题:iOS监听signal捕捉崩溃

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