Dokit支持iOS本地crash查看功能

  • 时间:
  • 浏览:0

下面,大伙儿儿就来看下这两类异常应当何如捕获。

都里能看了,通过上述调用堆栈大伙儿儿无法定位大问题。不会,大伙儿儿还要拿到意味Crash的NSException,从中获取异常的名称、意味和调用堆栈,事先才能准选折 位大问题。

参考捕获Objective-C异常时处里覆盖大问题的思路,大伙儿儿也都里能先将已有的异常处里函数进行保存,不会在大伙儿儿的异常处里函数执行事先,再调用事先保存的异常处里函数就都里能了。具体实现的代码如下:

不会,在调试Unix信号的捕获总要发现没法 进入异常处里函数。这是为啥会 呢?难道是大伙儿儿对于Unix信号的捕获没法 生效么?虽然 并总要事先的。主好多好多 不会Xcode调试器的优先级会高于大伙儿儿对于Unix信号的捕获,系统抛出的信号被Xcode调试器给捕获了,就越多再再往上抛给大伙儿儿的异常处里函数了。

Unix信号:只在程序中处里,处里程序老是在所处错误的程序上调用。

所有Mach异常总要host层被ux_exception转换为相应的Unix信号,并通过threadsignal将信号投递到出错的程序。iOS中的 POSIX API 好多好多 通过 Mach 之上的 BSD 层实现的。如下图所示:

DoraemonKit项目截图:

上一节介绍了Objective-C异常,本节来介绍下Mach异常,那究竟哪几种是Mach异常呢?在回答这个大问题事先,大伙儿儿先来看下一些相关的知识。

通过前面的介绍,相信大伙儿儿对何如捕获Crash有了一定的了解,下面引用《Mach异常》中的一张图对事先的内容做事先总结,如下所示:

写这篇文章主好多好多 为了才能让大伙儿儿对于DoraemonKit中Crash查看工具有事先快速的了解。不会时间仓促,被委托人水平有限,如有错误之处欢迎大伙儿儿批评指正。

在大伙儿儿设置被委托人的异常处里函数事先,先保存已有的异常处里函数。在处里异常的事先,大伙儿儿被委托人的异常处里函数处里完毕事先,还要将异常抛给事先保存的异常处里函数,代码如下:

不会大伙儿儿会虽然 既然Unix信号都里能捕获底层的Mach异常,那为哪几种必须捕获Objective-C异常呢?虽然 是都里能捕获的,好多好多 对于这个应用级的异常,让你发现调用堆栈里并没没法 你的代码,无法定位大问题。累似 ,数组越界这个Objective-C异常的代码如下:

到这里,就基本完成对于Unix信号的捕获了。

BSD层则在Mach之上,提供一套可靠且更现代的API,提供了POSIX兼容性。

既然最终以信号的法子投递到出错的程序,没法 就都里能通过注册signalHandler来捕获信号:

《漫谈iOS Crash分派框架》

《iOS异常捕获》《iOS内功篇:浅谈Crash》《iOS Mach异常和signal信号》《浅谈Mach Exceptions》《iOS监控编程之崩溃监控》《Mach异常》

在DoraemonKit中,大伙儿儿直接将Crash保存到沙盒的cache目录中,不会进行查看。

Mach异常:允许在程序里或程序外处里,处里程序通过Mach RPC调用。

这里还要注意的一些是,对于大伙儿儿监听的信号总要保存事先的异常处里函数。

那该为啥做才能阻止生成捕获Unix信号的日志呢?在DoraemonKit中采取的法子是在Objective-C异常捕获到Crash事先,主动调用exit(0)不会kill(getpid(), SIGKILL)等法子让程序退出。

运行后控制台输出日志:

Mach微内核所含哪有几个基本的概念:

基于以上意味,大伙儿儿选折 了基于Unix信号的法子来捕获异常。

捕获Mach异常不会Unix信号都都里能抓到Crash事件,这里大伙儿儿使用了Unix信号法子进行捕获,主要意味如下:

在iOS的开发过程中,会老是老是出现各种各样的Crash,那何如才能捕获哪几种不同的Crash呢?虽然 对于常见的Crash而言,都里能分为两类,一类是Objective-C异常,另一类是Mach异常,一些常见的异常如下图所示:

iOS系统自带的 Apple’s Crash Reporter 记录在设备中的Crash日志,Exception Type项通常会所含事先元素:Mach异常和Unix信号。

累似 ,Exception Type:EXC_BAD_ACCESS (SIGSEGV)表示的意思是:Mach层的EXC_BAD_ACCESS异常,在host层被转加带SIGSEGV信号投递到出错的程序。下图展示了从Mach异常转加带Unix信号的过程:

更多信号的释义都里能参考《iOS异常捕获》。

在捕获Objective-C异常时,使用Xcode进行调试都里能清晰地看了调用流程。先调用了意味Crash的测试代码,不会进入异常处里函数捕获Crash日志。

即使捕获Crash的过程没法 大问题,还是会所处一些捕获必须的请况。累似 ,短时间内内存急剧上升,这个事先APP会被系统kill掉。不会,此时的Unix信号是SIGKILL,该信号是用来立即刚开始程序的运行,必须被阻塞、处里和忽略。不会,无法对此信号进行捕获。

针对内存泄露,推荐一款iOS内存泄露检测工具MLeaksFinder:MLeaksFinder

还有一些Crash虽然 都里能分派,不会日志中没法 被委托人的代码,定位十分困难。野指针正是没法 ,针对这个请况,推荐参考《何如定位Obj-C野指针随机Crash》系列文章:

《何如定位Obj-C野指针随机Crash(一):先提高野指针Crash率》《何如定位Obj-C野指针随机Crash(二):让非必现Crash变成必现》《何如定位Obj-C野指针随机Crash(三):何如让Crash自报家门》

好多好多 ,在DoraemonKit中大伙儿儿采用了NSSetUncaughtExceptionHandler 对于Objective-C异常进行捕获。

这里的参数DoraemonUncaughtExceptionHandler好多好多 异常处里函数,它的定义如下:

Sets the top-level error-handling function where you can perform last-minute logging before the program terminates.

不会,不会大伙儿儿要调试Unix信号的捕获时,必须直接在Xcode调试器里进行调试,一般使用的调试法子是:

以上介绍了哪有几个常见的Objective-C异常,接下来大伙儿儿来看下何如捕获Objective-C异常。

那不会总要在开发过程中,大伙儿儿应当何如捕获哪几种异常的信息呢?

运行后控制台输出日志:

在了解到Mach一些相关概念事先,大伙儿儿来看下哪几种是Mach异常?这里引用《漫谈iOS Crash分派框架》中对于Mach异常的解释。

累似 上一节中捕获Objective-C异常的思路,先注册事先异常处里函数,用于对信号的监控。代码如下:

为了使得DoraemonKit不影响一些Crash分派工具,这里在注册异常处里函数之总要先保存事先不会注册的异常处里函数。不会在大伙儿儿的处里函数执行事先,再调用事先保存的处里函数。事先,DoraemonKit就越多再对事先注册的Crash分派工具产生影响了。

一般来说,常见的Objective-C异常包括以下几种:

思路有了,该何如实现呢?通过Apple的文档都里能知道,有事先获取事先异常处里函数的API,好多好多 NSGetUncaughtExceptionHandler ,通过它大伙儿儿就都里能获取事先的异常处里函数了,代码如下:

运行后控制台输出日志:

累似 捕获Objective-C异常不会老是老是出现的大问题,在集成多个Crash分派工具时,不会大伙儿儿对于相同的信号都注册了异常处里函数,没法 后注册的不会覆盖掉前面注册的,意味前面注册的异常处里函数必须正常工作。

正如事先所述,在同事先APP中集成多个Crash分派工具之不会所处强行覆盖的大问题,即后注册的异常处里函数会覆盖掉事先注册的异常处里函数。

在日常开发中不会测试过程中,大伙儿儿的应用之不会老是老是出现Crash的大问题。对于累似 大问题大伙儿儿要抱着零容忍的态度,不会不会线上老是老是出现了累似 大问题,不会严重影响用户的体验。

这里还要注意的是:对于事先APP来说,之不会集成多个Crash分派工具,不会大伙儿儿都调用了NSSetUncaughtExceptionHandler来注册异常处里函数,没法 后注册的不会覆盖掉前面注册的,意味前面注册的异常处里函数必须正常工作。

到这里,就基本完成对于Objective-C异常的捕获了。

通过底下的代码大伙儿儿都里能看了,在异常所处的事先,异常名称、老是老是出现异常的意味以及异常的堆栈信息都都里能拿到。拿到哪几种信息事先,保存到沙盒的cache目录,不会就都里能直接查看了。

不会大伙儿儿使用Unix信号进行捕获,得到的Crash日志如下:

不过,以上并也有法子都总要很方便。没法 大问题来了,有没法 更好的法子查看Crash日志?答案当然是肯定的。DoraemonKit的常用工具集中的Crash查看功能就处里了这个大问题,都里能直接在APP端查看Crash日志,下面大伙儿儿来介绍下Crash查看功能的实现。

那应当何如处里这个覆盖的大问题呢?虽然 思路很简单,在大伙儿儿调用NSSetUncaughtExceptionHandler注册异常处里函数事先,先拿到已有的异常处里函数并保存下来。不会在大伙儿儿的处里函数执行事先,再调用事先保存的处里函数就都里能了。事先,底下注册的就越多再对事先注册的产生影响了。

不会大伙儿儿虽然 大伙儿儿这个项目还都里能一段话,点上一颗star吧。

不会大伙儿儿既捕获了Objective-C异常,又捕获了Mach异常,没法 当所处Objective-C异常的事先就会老是老是出现两份Crash日志。

意思好多好多 通过这个API设置了异常处里函数事先,就都里能在程序终止前的最后一刻进行日志的记录。这个功能正是大伙儿儿让你的,使用起来也比较简单,代码如下:

这里的DoraemonSignalHandler好多好多 监控信号的异常处里函数,它的定义如下:

不会Crash老是老是出现的事先恰好是在开发过程中,没法 开发者都里能根据Xcode的调用堆栈不会控制台输出的信息来定位大问题的意味。不会,不会是在测试过程中一段话就比较麻烦了。常见的并也有处里方案是:

一份是通过NSSetUncaughtExceptionHandler 设置异常处里函数生成的日志,另一份是通过捕获Unix信号产生的日志。这两份日志中,通过Unix信号捕获的日志是无法定位大问题的,不会大伙儿儿只还要NSSetUncaughtExceptionHandler 中异常处里函数生成的日志即可。

底下两节分别介绍了何如捕获Objective-C异常和Mach异常,本节主好多好多 总结一下实现的过程中,遇到的一些大问题。

目前的Crash查看好多好多 实现了最基本的功能,后续还还要不断完善。大伙儿儿不会有哪几种好的想法,不会发现大伙儿儿的这个项目有bug,欢迎大伙儿儿去github上提Issues不会直接Pull requests,大伙儿儿会第一时间处里,也都里能加入大伙儿儿的qq交流群进行交流,也希望大伙儿儿这个工具集合能在大伙儿儿的同时努力下,做得更加完善。

Unix信号有好多好多 种,删改的定义都里能在<sys/signal.h>中找到。下面列举大伙儿儿所监控的常用信号以及它们的含义:

不会是在开发过程中,Objective-C异常意味的Crash会在Xcode的控制台输出异常的类型、意味以及调用堆栈,根据哪几种信息大伙儿儿才能更慢定位异常的意味并进行修复。

顾名思义,Objective-C异常好多好多 所处OC层面(iOS库、第三方库老是老是出现错误时)老是老是出现的异常。在介绍何如捕获Objective-C异常事先大伙儿儿先来看下常见的Objective-C异常包括哪几种。

运行后控制台输出日志:

Mach异常是指最底层的内核级异常,被定义在 <mach/exception_types.h>下 。每个thread,task,host总要事先异常端口数组,Mach的部分API暴露给了用户态,用户态的开发者都里能直接通过Mach API设置thread,task,host的异常端口,来捕获Mach异常,抓取Crash事件。

运行后控制台输出日志:

Mach的职责主好多好多 程序和程序抽象、虚拟内存管理、任务调度、程序间通信和消息传递机制等。

通过底下的代码大伙儿儿都里能看了,在异常所处时,信号名、调用堆栈、程序信息等都都里能拿到。拿到哪几种信息事先,保存到沙盒的cache目录,不会就都里能直接查看了。

DoraemonKit项目地址:https://github.com/didi/DoraemonKit

这里有一些还要注意的是,过滤掉了第一行日志。这是不会注册了信号崩溃的回调法子,系统会来调用,将记录在调用堆栈上,不会为了处里困扰将此行日志过滤掉。

在处里异常的事先,大伙儿儿被委托人的异常处里函数处里完毕事先,还要将异常抛给事先保存的异常处里函数,代码如下:

上图来自于Apple的Mac Technology Overview,对于Kernel and Device Drivers 这个层而言,OS X与iOS架构大体上是一致的。其中,内核部分总要XNU,而Mach好多好多 XNU的微内核核心。

虽然 Apple不会给大伙儿儿提供了捕获Objective-C异常的API,好多好多 NSSetUncaughtExceptionHandler 。大伙儿儿先来看下官方文档是为啥描述的: