安卓 Android 原生应用 Native 崩溃

发布于 2025-01-21 18:29:51 字数 1977 浏览 9 评论 0

捕获流程

  1. 编译端:编译 C/C++ 代码时,需要将带符号信息的文件保留下来。
  2. 客户端:捕获到崩溃时候,将收集到尽可能多的有用信息写入日志文件,然后选择合适的时机上传到服务器。
  3. 服务端:读取客户端上报的日志文件,寻找适合的符号文件,生成可读的 C/C++ 调用栈。

捕获难点

怎样保证在各种极端情况下依然可以生成崩溃日志。

Breakpad 是最成熟方案

  • 情况一:文件句柄泄漏,导致创建日志文件失败,怎么办?
    • 应对方式:我们需要提前申请文件句柄 fd 预留,防止出现这种情况。
  • 情况二:因为栈溢出了,导致日志生成失败,怎么办?
    • 应对方式:为了防止栈溢出导致进程没有空间创建调用栈执行处理函数,我们通常会使用常见的 signalstack。在一些特殊情况,我们可能还需要直接替换当前栈, 所以这里也需要在堆中预留部分空间。
  • 情况三:整个堆的内存都耗尽了,导致日志生成失败,怎么办?
    • 应对方式:这个时候我们无法安全地分配内存,也不敢使用 stl 或者 libc 的函数,因为它们内部实现会分配堆内存。这个时候如果继续分配内存,会导致出现堆破坏或者二次崩溃的情况。Breakpad 做的比较彻底,重新封装了
  • 情况四:堆破坏或二次崩溃导致日志生成失败,怎么办?
    • 应对方式:Breakpad 会从原进程 fork 出子进程去收集崩溃现场,此外涉及与 Java 相关的,一般也会用子进程去操作。这样即使出现二次崩溃,只是这部分的信息丢失,我们的父进程后面还可以继续获取其他的信息。在一些特殊的情况,我们还可能需要从子进程 fork 出孙进程。

崩溃率计算

UV 崩溃率 = 发生崩溃的 UV / 登录 UV

如何客观地衡量稳定性(ANR)

  1. 使用 FileObserver 监听 /data/anr/traces.txt ​ 的变化
    • 海外可以使用 Google Play 服务,而国内微信利用 HardCoder 。HC 框架是一套独立于安卓系统实现的通信框架,它让 App 和厂商 ROM 能够实时“对话”了,目标就是充分调度系统资源来提升 App 的运行速度和画质,切实提高大家的手机使用体验,向厂商获取了更大的权限。
  2. 监控消息队列的运行时间
    • 这个方案无法准确地判断是否真正出现了 ANR 异常,也无法得到完整的 ANR 日志。
  3. 应用退出的情形
    • 主动自杀:Process.killProcess()、exit()
    • 崩溃:出现了 Java 或 Native 崩溃。
    • 系统重启:系统出现异常、断电、用户主动重启等,我们可以通过比较应用开机运行时间是否比之前记录的值更小。
    • 被系统杀死:被 low memory killer 杀掉、从系统的任务管理器中划掉等。
    • ANR
  4. 根据应用的前后台状态,我们可以把异常退出分为前台异常退出和后台异常退出。“被系统杀死”是后台异常退出的主要原因,当然我们会 更关注前台的异常退出的情况 ,这会跟 ANR、OOM 等异常情况有更大的关联。
  5. 异常率计算: UV 异常率 = 发生异常退出或崩溃的 UV / 登录 UV

参考 Android 平台 Native 代码的崩溃捕获机制及实现

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

合约呢

暂无简介

文章
评论
26 人气
更多

推荐作者

狼性发作

文章 0 评论 0

美煞众生

文章 0 评论 0

黑凤梨

文章 0 评论 0

慕巷

文章 0 评论 0

virou

文章 0 评论 0

两仪

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文