前言
日志收集服务,成熟的开源项目很多,如 KSCrash,plcrashreporter,CrashKit 。追求方便省心,对于保密性要求不高的程序来说,也可以选择各种一条龙Crash统计产品,如 Crashlytics,Hockeyapp ,友盟,Bugly 。
正文
Mach异常是什么?
Mach是一个XNU的微内核核心,Mach异常是指最底层的内核级异常,被定义在
Exception Type: EXC_BAD_ACCESS (SIGSEGV)//Mach层的EXC_BAD_ACCESS异常,在host层被转换成SIGSEGV信号投递到出错的线程。
Exception Subtype: KERN_INVALID_ADDRESS at 0x041a6f3
Mach异常是如何与Unix信号建立联系?
所有Mach异常都在host层被ux_exception转换为相应的Unix信号,并通过threadsignal将信号投递到出错的线程。
iOS中的 POSIX API 就是通过 Mach 之上的 BSD 层实现的。
从 EXC_BAD_ACCESS (SIGSEGV) ,可以看出Mach层的EXC_BAD_ACCESS异常,在host层被转换成SIGSEGV信号投递到出错的线程。既然最终以信号的方式投递到出错的线程,那么就可以通过注册signalHandler来捕获信号:
signal(SIGSEGV,signalHandler);
抓取crash事件可以通过捕获Mach异常、或Unix信号
这两种方式 优选Mach异常,因为Mach异常处理会先于Unix信号处理发生
ps:转换Unix信号
因为硬件产生的信号(通过cpu陷阱)被Mach层捕获,然后才转换为对应的Unix信号;苹果为了统一机制,于是操作系统和用户产生的信号(通过调用kill和pthread_kill)也首先沉下来被转换为Mach异常,再转换为Unix信号。--》转换Unix信号是为了兼容更为流行的POSIX标准(SUS规范),这样不必了解Mach内核也可以通过Unix信号的方式来兼容开发