unity崩溃查找
android崩溃日志收集
-
直接使用logcat日志定位
unity自己会捕获崩溃,然后在 logcat 输出崩溃堆栈,不管是 java、c#、c++ 崩溃都可以
因此只要获得logcat日志,就能获得崩溃堆栈- 使用logcat获得日志
- 使用dropbox获得日志
- 使用bugreport获得日志
-
手动转储崩溃日志
主要考虑3个部分:- c# 异常
这一部分已经被unity处理,会通过 Debug.Log 打印,只需要通过 Application.logMessageReceived 捕获日志并写入文件即可
原理参考 捕获全局异常
代码参考 unity日志输出到文件 - java 异常
可以使用 Thread.setDefaultUncaughtExceptionHandler 捕获 java 异常并写入文件中
原理参考 用代码捕获android崩溃日志
代码参考 unity崩溃输出到文件 - c++ 异常
这一部分已经被unity处理,会转成 java 异常抛出,所以不需要额外处理
- c# 异常
ios崩溃日志收集
-
使用自带的崩溃日志
-
手动转储崩溃日志
- IOS只有C++和C#两层,对于C#来说,和Android是一模一样的,不用多说。
对于C++这层,Unity已经为ios提供了一个crash report模块,他需要我们将工程生成好后,将 Classes/Crashreport.h 里面的 ENABLE_CUSTOM_CRASH_REPORTER 设置为1,
这样在c++ crash后,unity会为我们生存crash文件,等下次启动后,可以通过crashreport这个模块访问这些dmp文件,这些dmp文件都是ios上的标准dmp文件,可以使用ios的开发工具symbolicatecrash来查看。
unity内置的crash report其实也是采用了第三方的库plcrashreport来实现的,这个库在ios上的应用很多。 - 另外对于ios,其实也提供了一个函数NSSetUncaughtExceptionHandler ,用来当那些未捕捉的异常发生时,进入这个处理,可以拦截一些东西,
但是一些比如内存访问错误直接就退出了,不会进到这里,另外进到这里之后程序还是会退出,只是让我们可以记录一下,不过有了unity自带的crashreport 这个也就没啥用了。 - 还有在unity对ios的c#运行中,在player setting里面有个对代码的运行优化,选择slow but safe 还是fast but no exception,如果选择前者,所有c#的执行错误都会像脚本一样被catch住,会报c#的exception,
如果后者就不会,就直接不catch了,会造成程序退出,但是运行效率是高的,我们通常选择slow but safe。这是mono架构的特性。
- IOS只有C++和C#两层,对于C#来说,和Android是一模一样的,不用多说。
调用堆栈地址还原成符号
-
符号表介绍
- 首先符号表根据使用的编译参数不同,分为2种,debug 和 public,都能把地址转成函数名,不同的是 debug 会多一些信息,要调试的话只能用 debug 符号表
debug 符号表后缀为 .dbg.so, public 符号表后缀为 .sym.so,一般 unity 引擎只有 public 符号表,你的游戏逻辑会同时生成 debug 和 public 符号表
在使用的时候要移除 .dbg 或 .sym 后缀,比如 libunity.sym.so 改成 libunity.so - 其次debug和release也会生成不同的符号表,所以一共有4种符号表,debug版本的debug、public符号表,release版本的debug、public符号表
- 首先符号表根据使用的编译参数不同,分为2种,debug 和 public,都能把地址转成函数名,不同的是 debug 会多一些信息,要调试的话只能用 debug 符号表
-
首先定位符号表位置
- Android
参考 Unity 用户手册 2020.3 (LTS)/平台开发/Android/构建 Android 应用程序/Android symbols- unity引擎只有public 符号表,位于
/PlaybackEngines/AndroidPlayer/Variations///Symbols//
开启 Strip Engine Code enabled 后,libunity 会生成一个裁剪后的符号表 /Temp/StagingArea/symbols// - 用户代码只有开启 IL2CPP ,才会有符号表
Il2cpp.so 是游戏逻辑编译出来的,其符号表在打包工程时生成- Build Settings 勾选 Create symbols.zip
- 打包后会在 apk 输出目录生成 {应用名称}-{内部版本号}-v{版本号}.symbols.zip,
里面就包含 Il2cpp.so 的 public 和 debug 符号表,以及 libunity 经过代码裁剪后的public符号表
- unity引擎只有public 符号表,位于
- Android
-
然后使用符号表把地址转成函数
假设堆栈是这样的文章来源:https://www.toymoban.com/news/detail-704951.htmlI/DEBUG(242): backtrace: I/DEBUG(242): #00 pc 006d4960 /data/app-lib/com.u.demo-1/libunity.so I/DEBUG(242): #01 pc 006d4c0c /data/app-lib/com.u.demo-1/libunity.so
则通过以下命令可以获得 006d4960 对应的函数名称
arm-linux-androideabi-addr2line -f -C -e {unity安装目录}/PlaybackEngines/AndroidPlayer/Variations/{mono或il2cpp}/Release/Symbols/armeabi-v7a/libunity.sym.so 006d4960
-f - Show function names
-C - Demangle function names
-e - Set the input file name
arm-linux-androideabi-addr2line 位于 {NDK安装目录}/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line文章来源地址https://www.toymoban.com/news/detail-704951.html
unity日志输出到文件
[DefaultExecutionOrder(-10000)]
public clas
到了这里,关于unity崩溃查找的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!