【问题标题】:How do I get more call stack depth in crash dumps on Android?如何在 Android 上的故障转储中获得更多调用堆栈深度?
【发布时间】:2015-06-01 18:01:23
【问题描述】:

我有一些使用 NDK 的 C++ 代码。当 C++ 代码(在设备上;而不是通过模拟器)发生崩溃时,我会得到一个墓碑(崩溃转储),其中包含一个始终为 2 级深的调用堆栈:

I/DEBUG   ( 5089): pid: 5048, tid: 5062  >>> com.example.site <<<
I/DEBUG   ( 5089):          #00  pc 0059e08c  /data/data/com.example.site/lib/libexample.so (_ZNK10MyNamespaceAPI11MyClass12GetDataEv)
I/DEBUG   ( 5089):          #01  lr 5bc9ef2c  /data/data/com.example.site/lib/libexample.so
I/DEBUG   ( 5089):     5cc6e764  5bce3070  /data/data/com.example.site/lib/libexample.so
I/DEBUG   ( 5089):     5cc6e774  5bce309c  /data/data/com.example.site/lib/libexample.so
I/DEBUG   ( 5089):     5cc6e784  5bce2af4  /data/data/com.example.site/lib/libexample.so
I/DEBUG   ( 5089):     5cc6e788  5c27ea9c  /data/data/com.example.site/lib/libexample.so

有没有办法配置我的应用或 Android 以在打印到故障转储的调用堆栈中提供更多细节和深度?究竟是什么决定了这一点?我见过一些示例,其中人们获得了高达 15 级的调用堆栈深度。

【问题讨论】:

标签: android c++ android-ndk crash crash-dumps


【解决方案1】:

回溯机制在过去几年中不断发展,它可以显示尽可能多的帧(最多 32 个,IIRC 的固定限制)。如果有东西阻止它在堆栈中走得更远,它将提前停止。

ARM 上的调用机制将返回地址放入链接寄存器 (LR),但允许编译器将其溢出到堆栈中。对于“noreturn”功能,它在技术上根本不需要设置它。有一些汇编程序伪操作添加了元数据,可帮助展开程序找出可以找到返回地址的位置,并且在最新版本的 Android 中应该都可以工作。

当你得到一个两深的堆栈跟踪时,这意味着在当前方法上展开失败,它只能显示程序计数器(PC)的值和恰好在 LR 中的值。

确保您使用-g 进行编译以启用调试。

失败的函数是直接从 JNI 调用的吗?在一些旧版本的 Android 中,由于代码的结构方式,跟踪会在 JNI 调用桥接处停止,尽管这在 Dalvik back in 2011 中已修复。不过,最近的设备使用 Art,我希望它有不同的做事方式。

类似问题here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-16
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多