如何高效定位Unity安卓开发中的闪退问题(转自侑虎科技公众号)

地址:

https://mp.weixin.qq.com/s?__biz=MzI3MzA2MzE5Nw==&mid=2668910435&idx=1&sn=6e93ea2c73fa43fc08ad480187414aa8&chksm=f1c9fb11c6be720797850aea7476a3c5130717afb609020686afc4a3e3d025918076f25c2f7d&mpshare=1&scene=1&srcid=0627PiT8k6r7CSfnOEiX4oph#rd


Unity安卓开发遇到闪退基本都会是这个错误“Fatal signal 11 (SIGSEGV)”,意思就是内存引用可能出现错误,下面还有很多“#00 pc 00a3b772c #01 pc 006a4310”, 它就是错误栈但是如果没有带符号表的so是看不懂的。


Unity的源码都是C++写的,为了让应用层使用C#开发,Runtime环境下对外封装了UnityEngine.DLL,这样应用层访问UnityEngine.DLL,由它再访问底层C++部分代码。前面我们讲的Fatal Signal 11 (SIGSEGV)其实就是挂在了Unity的底层代码中。


Unity的底层代码我们是改不了的,为了解决闪退只有一个办法就是找到调用它的地方,绕过底层的闪退。通过我的经验,大部分闪退都是由于应用层传递了错误的数据,引擎内部可能还会对传入的数据进行传递或转换,过程中如果出现故障就挂了。


最简单的办法就是打包的时候勾选Development Build。


勾选Development Build后,当出现闪退以后连上Logcat就能直接看到问题在哪里,由于我们用的是il2cpp打的包,这里直接能看到完整引起闪退的日志。


上述方法也存在一个问题,总不能每次打包都打Debelopment Build版本吧,如果已经是发布出去的版本出现闪退如何定位呢?如图所示,Unity已经将自己内部的符号表公开出来了,找到il2cpp或者Mono下的Symbols下的.so即可。


接着我要在Android SDK中找到“arm-linux-androideabi-addr2line”用来还原这个错误栈。

注意:将需要还原的地址依次输入在命令的最后即可


如果你的项目是il2cpp,那么每次打包后都需要拿到生成的il2cpp符号表so。这里引用Unity官方的一篇文章:

https://support.unity3d.com/hc/en-us/articles/115000177543-Where-I-can-get-the-symbols-file-for-the-libil2cpp-so-library-in-an-Android-IL2CPP-build-to-symbolicate-call-stacks-from-crashes-on-my-production-builds-

 

完整代码请前往UWA Blog查看 


有了so以后就可以用“arm-linux-androideabi-addr2line”来还原闪退栈了。有时候一些重要的闪退现场只有QA那里才有,大家也不希望他们报上来的BUG就是闪退两个字吧。我们最后希望QA上报BUG的时候就把闪退的栈报上来,这样程序就方便多了,帮他们做个工具吧。


在Android SDK目录下拷贝出“adb.exe  AdbWinApi.dll AdbWinUsbApi.dll fastboot.exe ”这些adb需要的依赖库。


当QA测试出现闪退的时候,双击run.bat即可提取日志(我一般让他们搞个快捷方式放在桌面上)。这里需要注意的是千万不要让他们用360手机助手,因为它会持续占用adb端口,别的手机助手都没这问题,比如豌豆荚、PP助手。

完整代码请前往UWA Blog查看 


如果大家接了闪退汇报的SDK,也可以将so传上去,我用的是Fabirc每次都把il2cpp的so传上去,看闪退也挺方便。


另外,闪退需要解决,但是异常错误也需要解决。前面我们介绍过挂在Unity底层会引起闪退,但是如果挂在我们自己写的代码中那就是异常了,比如常见的空指针数组越界等。


这里提供一个思路,方便我们后续提交Bug:在代码中监听“Application.logMessageReceived”的事件,统计到了异常直接输出显示在屏幕中。这样QA在报BUG的时候可以截个屏,程序看到就方便修改了。


猜你喜欢

转载自blog.csdn.net/dengshunhao/article/details/80825123