android - 如何在 Flutter 中表示 libapp.so 堆栈跟踪?
问题描述
在 Google Play 控制台中,有时我会看到如下崩溃报告:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
pid: 0, tid: 0 >>> com.blackoutage.game <<<
backtrace:
#00 pc 00000000003080f0 /data/app/~~X6gyE3SkREkb9PZZqeHzjA==/com.blackoutage.game-7OdYWe4UMLRMee8enANExA==/split_config.arm64_v8a.apk!lib/arm64-v8a/libflutter.so (offset 0xafa000)
#00 pc 0000000000306ad4 /data/app/~~X6gyE3SkREkb9PZZqeHzjA==/com.blackoutage.game-7OdYWe4UMLRMee8enANExA==/split_config.arm64_v8a.apk!lib/arm64-v8a/libflutter.so (offset 0xafa000)
#00 pc 000000000065ebc4 /data/app/~~X6gyE3SkREkb9PZZqeHzjA==/com.blackoutage.game-7OdYWe4UMLRMee8enANExA==/split_config.arm64_v8a.apk!lib/arm64-v8a/libflutter.so (offset 0xafa000)
#00 pc 000000000051e4a8 /data/app/~~X6gyE3SkREkb9PZZqeHzjA==/com.blackoutage.game-7OdYWe4UMLRMee8enANExA==/split_config.arm64_v8a.apk!lib/arm64-v8a/libapp.so (offset 0x1000)
#00 pc 0000000000565c9c /data/app/~~X6gyE3SkREkb9PZZqeHzjA==/com.blackoutage.game-7OdYWe4UMLRMee8enANExA==/split_config.arm64_v8a.apk!lib/arm64-v8a/libapp.so (offset 0x1000)
#00 pc 000000000063925c /data/app/~~X6gyE3SkREkb9PZZqeHzjA==/com.blackoutage.game-7OdYWe4UMLRMee8enANExA==/split_config.arm64_v8a.apk!lib/arm64-v8a/libflutter.so (offset 0xafa000)
#00 pc b4000071fdfd5200 <unknown>
从libflutter.so
(https://github.com/flutter/flutter/wiki/Crashes)符号化堆栈跟踪非常容易。根据上面的日志,我可以说颤动中的某些东西崩溃了,但是要修复这些错误,我还需要符号化来自 的痕迹libapp.so
,我该怎么做?
解决方案
首先,如果可以,请尝试使用集成解决方案,例如 Sentry ( https://pub.dev/packages/sentry_flutter )。它会自动捕获堆栈跟踪并尝试对其进行符号化。如果您的应用程序被剥离,您还可以将符号文件上传到他们的服务器,它们将对其进行符号化。
其次,如果你想手动完成,这里有一些见解。我之前一直在为这种符号化而苦苦挣扎,而且互联网上似乎没有足够的信息(所以让我在互联网上添加一点信息;))。
有趣的libapp.so
是,它是一个普通.so
文件(动态链接库)。它不是一种特殊的自制特定于 Flutter 的格式。相反,即使您编写 C/C++ 程序并对其进行编译,它也是相同的 ELF 格式。有了这些知识,您将立即意识到,符号化 Flutter 堆栈跟踪与符号化普通 C/C++/... 代码没有区别。
因此,您可能需要对传统的 C/C++ 世界有所了解。例如,我建议阅读经典 CSAPP 教科书的“链接器”章节,它很好地解释了一切。然后您将完全了解什么是.so
文件,如何符号化 C/C++ .so 文件的堆栈跟踪等。
那么你做 Flutter 的符号化应该没有问题。但是在这里我也一步一步地写下要做什么:首先,当您构建apk而不包含其中的调试信息时,您使用split-debug-info标志并单独获取调试信息文件。符号化将需要此调试信息文件。然后,使用传统工具操作传统.so
文件,例如addr2line
,获取给定的源代码行号pc
。当然,诸如此类的高级工具ndk-stack
也会有所帮助。或者你可以写下你自己的脚本调用addr2line
等等。
推荐阅读
- linux - Docker Desktop 使用 PowerShell 修改目录后,如何将目录从主机复制到容器?(宿主 windows 容器 ubuntu)
- javascript - 已经坐了一个小时,无法弄清楚为什么找不到 /js/bootstrap.min.js
- plot - 在 Gnuplot 中是否可以在曲面图下的 xyplane 上绘制 2D 图?
- scala - Spark scala异常重载方法值foreach
- vue.js - Vue/Tailwind 中的浮动标签
- javascript - 如何获取 react-leaflet 地图的边框并检查地图内的标记?
- email - Gmail Android 渲染?忽略样式头标签 2021 中的所有 CSS
- python - 使用 Papermill 生成笔记本时如何将 Jupyter Notebook 标记为可信
- docker - Kubernetes Nginx Ingress 使用 hosts 文件返回 502 Bad Gateway
- javascript - Python Selenium send_keys() 文本文件内空白区域的错误原因