Crash Report,这在大型软件开发领域是很常见的功能,就是能够当程序崩溃退出后,能够将崩溃时的信息,最好是携带dmp文件发送给服务器,这样开发人员既可以获得分发出去的客户端的崩溃率统计,也可以针对出现的错误进行及时的纠正,之前在PC的端游时代,这是很常见的做法,最近进行了在手游上的关于crash report的相关研究,并且为项目编写了一个相对完善的CrashReport模块。
这个模块的来源于手游项目正式上线,但是很多玩家反馈闪退,但是我们只能听到反馈闪退,却不能找到原因,只能凭脑袋去猜,是不是内存不够,机器配置太差,然后去尽可能优化性能,于是老大开始喊我们需要一个Crash Report, 于是就花2个星期完善了一个可以正式使用的Crash Repoter,项目基于Unity3D,在Android和Ios上做crash report 对我还是第一次,所以还是抱有了极大的兴趣。
1 Android 平台。
其实CrashReport也不应该是只有Crash了才Report,各种错误和潜在会导致Crash的问题也应该report上去。对于基于Unity3D的Android应用来说,自底到上可以分为三层:C++,Java和C#。 android是基于linux的系统,最底下的各种so a库就是C++的部分,android系统本身的相关逻辑则是java,U3D则使用了C#开发逻辑,所以我们采集问题也要从这三块分别着手。
C#
c#的错误很好处理,这层U3D完全封装好了,C#层会出现warning error和exception,在android下这几种情况都不会导致crash,都会被UNITY3d接住,但是我们需要知道并报告给服务器,U3D有接口Application.RegisterLogCallback(),可以让C#层发生上面的问题时被我知道,我们只要写这个callback,然后在里面给服务器就行了。
Java
java层的错误就是各种java exception,对于java,如果对于我们catch了的exception,不会导致crash,会按照我们的catch行为执行,对于那些我们没有catch的exception,是会crash的,还会在adblog上打印出来,我们需要获知这些exception,我们可以采用java中的接口Thread.setDefaultUncaughtExceptionHandler来重新设置这个对未catch的exeption的处理,在我们自己的handler中基本做的事情就是首先把这个exceptio报告给服务器,然后并不让程序退出,让程序尽可能活下去。
C++
C++中出现的问题通常就是很严重的了,这里也分两种,一种是普通的一些异常,这取决于你是否catch了,如果没有catch,默认就是abort的,也就是crash了,还有一些比如对内存的非法访问,就直接在linux中产生了一个结束信号,把进程结束了,也是crash。对于C++我们先后尝试了两种方案,第一种就是采用捕获linux的信号量,程序异常退出总是有信号的,可以使用linux 下的sigaction来设置对这些信号的捕获处理,比如我们捕获了SIGILL SIGABRT SIGFPE SIGSEGV SIGPIPE SIGBUS SIGSTKFLT,这样对于异常的