Notifications
Article
Unity Performance Reporting 测试
Updated 4 months ago
715
3
现在当手游准备上线对外发布时,都需要能够在服务器上记录每一个游戏客户端的各种异常和崩溃日志,方便开发人员分析日志修改bug。以前使用Unity开发的手游需要通过第三方SDK来实现这个功能,这就要求开发人员需要在游戏内配置接入SDK,实现日志记录,同时iOS和Android的配置方式也有差异,对于开发人员不够友好。
现在Unity引擎已经内置了一套可以进行异常与崩溃日志记录的服务——Performance Reporting。下面我们来看看如何使用它。

一、配置说明Performance Reporting

1.从Unity 编辑器菜单的Window>Services打开Services面板并找到Performance Reporting。
2.点击进入Performance Reporting子面板,并开启此项服务。其中Capture Editor Exceptions可将编辑器处于PlayMode时的异常进行上报,大家可根据需要选择是否开启它。
3.那么,通常进行上述配置后,Performance Reporting准备工作就完成了。配置非常简单,并且是跨平台的,设置一次后,iOS和Android都会自动开启这个功能。
4.如果是iOS平台PlayerSettings中Script Call Optimization在发布时设为Fast but no Exceptions,崩溃日志会以uncaught managed exceptions进行上报记录。

二、示例测试

下面我们来通过简单的测试代码来体验一下Performance Reporting的异常与崩溃记录功能。
1.C#测试代码
public class TestCrashReport : MonoBehaviour { #if UNITY_IOS [DllImport ("__Internal")] private static extern void TestCrash(); #endif #if UNITY_ANDROID [DllImport("native-lib")] private static extern void TestCrash(); #endif //空引用 private void DoCSharpNullReference() { string str = null; Debug.Log(str.Length); } //数组越界 private void DoCSharpOutOfRange() { List<int> list=new List<int>(10); for (int i = 0; i < 10; i++) { list.Add(i); } Debug.Log(list[10]); } //调用Native代码会触发空指针而崩溃 private void DoNativeCrash() { TestCrash(); } private void OnGUI() { if (GUI.Button(new Rect(50, 50, 200, 200), "DoCSharpNullReference")) { DoCSharpNullReference(); } if (GUI.Button(new Rect(260, 50, 200, 200), "DoCSharpOutOfRange")) { DoCSharpOutOfRange(); } if (GUI.Button(new Rect(470, 50, 200, 200), "DoNativeCrash")) { DoNativeCrash(); } } }
C++测试代码:
//触发c++空指针 extern "C" { int *p= NULL; void TestCrash() { *p=1; } }
2.把上述代码放到一个Unity工程中,配置好Performance Reporting,分别打包到iOS和Android设备上进行测试,测试环境如下:
Unity版本:2017.4.6f1,
Script Backend:IL2CPP
iOS设备:iphone7,10.3.2
Android:Redmi note3,6.0.1
3.点击Services面板中的Go to Dshboard进入Performance Reporting页面
4.在使用异常和崩溃日志记录前,需要到Performance Reporting页面中上传符号表文件到Manager Symbols内。否则,堆栈信息内会存在symbols missing的内容。iOS平台要上传appname.dSYM文件,Android平台上传appname.symbols.zip。如果发布android平台app时,电脑处于联网状态时,会自动上传项目代码的符号表到服务器,iOS平台要自己手动上传appname.dSYM文件,项目使用的第三方库的符号表也要自己手动上传。
关于系统库符号表与App符号表的详细信息可以参考官方文档:https://docs.unity3d.com/Manual/UnityPerformanceReportingSymbols.html
5.运行app后,分别点击DoCSharpNullReference、DoCSharpOutOfRange、DoNativeCrash按钮,会触发C#的NullReference空指针异常、C#的OutOfRange数组越界异常、C++的访问空指针的崩溃。
首先在iOS设备上进行测试。在触发异常或崩溃后,等待一会日志就会出现在Performance Reporting页面内。其中,崩溃日志会在App重新启动后发送到Performance Reporting的服务器上,而异常信息会立即发送。如果遇到信息未更新可以刷新几次网页即可。
6.点击日志标题可以进入详细内容页面查看具体崩溃或异常堆栈:
C#的NullReference空指针异常堆栈:
C#的OutOfRange数组越界异常堆栈:
C++的访问空指针崩溃堆栈:
点击日志页面上面的“ALL METADATA”可以查看对应本条日志的设备信息、unity版本等内容
7.Android设备上的日志记录同样详细完整。
C#的NullReference空指针异常堆栈:
C#的OutOfRange数组越界异常堆栈:
ALL METADATA设备信息:
8.在Android平台上的Native崩溃日志中,libnative-lib.so就是由产生空指针崩溃的C++编译而来的。下面截图中那一行日志显示的是symbols missing for uuid: 5e9de2a3c184a7b06af016b2faa20de241fcae61,这就说明libnative-lib.so的符号表没有上传,需要按照前面提到的上传符号表方法,预先上传符号表文件。当符号表文件上传后,需要等待几分钟,然后之后的新日志就会包含可读的符号信息。但是符号表文件上传前记录的日志信息是不是再把正确的符号信息包含上去的。
9.如果App是运行在android模拟器上,也是可以捕获到异常和崩溃信息并上报的。
抓到的模拟器设备信息,这里我们使用的是Mumu模拟器
10.但是经过测试发现如果App打包没有包含x86指令集的SO,在模拟器上运行时,Native崩溃的日志记录信息是不完整的,无法帮助分析崩溃原因。这就要求如果需要记录各种机型和模拟器的崩溃日志,我们在打包Android时需要选择ARM+x86。

三、启用Performance Reporting中的crash report功能的Unity最低版本要求


Unity China
376
Comments
wl
wubin luo
4 months ago
Programmer
厉害了,之前一直接的是第三方的SDK,来记录一些崩溃和错误的堆栈信息,这下方便多了
0
Unity China Field Engineer - Programmer
👍赞
0
JianpingWang
4 months ago
Game scene editor & maker - Artist
如果有个收藏功能就更好了
0