对于Flutter来说,大部分crash其实发生在flutter engine中,即libflutter.so中,也就是native crash,对于这部分异常的堆栈,我们要如何进行还原呢。
首先我们要借助crash捕获工具捕获native crash,比如可以借助bugly,xcrash(https://github.com/iqiyi/xCrash),甚至是系统的crash dump日志,假设获取到如下堆栈,并将其内容保存到stacktrace.txt文件中
1 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
值得注意的是保存堆栈时,一定要将带第一行带星号的内容保留,因为堆栈还原时会对该行进行识别,再进行还原的。
1 | *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** |
然后需要获取对于App版本构建时使用的engine的revision,至于这个revision,我建议在打包的时候直接打入代码中,在crash的时候将其附加到额外信息中进行上报,比如放在BuildConfig中,亦或是扔到resources中,怎么处理方便怎么来,比如这里提供两种方式注入。
1 | android { |
flutter engine revision的值位于该文件中
1 | /path/to/flutter/bin/internal/engine.version |
假设此时该文件的内容为
1 | b863200c37df4ed378042de11c4e9ff34e4e58c9 |
可以通过如下url浏览该revision下的相关文件
1 | https://console.cloud.google.com/storage/browser/flutter_infra/flutter/b863200c37df4ed378042de11c4e9ff34e4e58c9 |
通过如下url直接下载对应的带符号表的libflutter.so文件
1 | https://storage.cloud.google.com/flutter_infra/flutter/b863200c37df4ed378042de11c4e9ff34e4e58c9/android-arm-release/symbols.zip |
这里注意,android-arm是debug构建时对应的文件,android-arm-profile是对应的性能检测构建时的文件,android-arm-release是release构建时对应的文件,对于线上版本,我们应该选择android-arm-release下的文件。如果是arm64的,则应该选择对应cpu abi的文件,如android-arm64-release
下载symblos.zip文件并将保存为symbols.zip文件,然后将其解压
1 | cd /path/to/symbols.zip/父目录 |
利用ndk-stack将堆栈进行还原
1 | /path/to/android-ndk-r16b/ndk-stack -sym /path/to/symbols/armeabi-v7a -dump /path/to/stacktrace.txt |
得到如下堆栈,可以看到发生crash的代码行数已经很清楚的展现出来了。
1 | ********** Crash dump: ********** |
如果你只想获取堆栈中某一行调用的代码行数,比如
1 | #01 pc 0014053b /data/app/com.vdian.flutter.wdb_buyer.example-da2lXUv43cG8AaX3DYe5RQ==/lib/arm/libflutter.so (offset 0x11d000) |
可以使用addr2line命令获取,首先得到pc的值0014053b,然后调用addr2line命令进行获取
1 | /path/to/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line -f -e /path/to/symbols/armeabi-v7a/libflutter.so 0014053b |
可以得到输出内容
1 | ~LogMessage |
如果你使用的是自己构建的engine引擎代码,那么在构建完成后,请务必保留带符号的libflutter.so文件,否则将无法还原堆栈。
如果你使用bugly进行native crash捕获,则可以借助bugly的符号表上传进行自动还原,见 https://bugly.qq.com/docs/user-guide/symbol-configuration-android/
