2

当我的 Android 应用程序崩溃(或遇到断言)时,我得到的回溯行数永远不会超过四行。搜索类似问题时,我只发现一两个地方提到了这一点,并且库存响应是:“确保它是一个调试版本”和“你可能有堆栈损坏”。我已经看到许多地方发生了许多崩溃,这些地方的框架看起来很准确,而且没有损坏的证据。

这是在调试构建中断言失败后从“adb logcat”中摘录的典型摘录:

I/DEBUG   (  187):     d28 3f824fc6ced25306  d29 3fabdfebb8fe14dc
I/DEBUG   (  187):     d30 fff0000000000000  d31 fffffffeffffffd2
I/DEBUG   (  187):     scr 88000010
I/DEBUG   (  187): 
I/DEBUG   (  187): backtrace:
I/DEBUG   (  187):     #00  pc 00018516  /system/lib/libc.so
I/DEBUG   (  187):     #01  pc 0000dc44  /system/lib/libc.so (abort+4)
I/DEBUG   (  187):     #02  pc 0000168d  /system/lib/liblog.so (__android_log_assert+88)
I/DEBUG   (  187):     #03  pc 00170bcc  /data/data/com.jsam.crag/lib/libmain.so (sim::TouchObserverController::HandleEvent(SDL_Event const&)+340)
I/DEBUG   (  187): 
I/DEBUG   (  187): stack:
I/DEBUG   (  187):          6f4be770  6f4be76c  [stack:17025]
I/DEBUG   (  187):          6f4be774  00000000  
I/DEBUG   (  187):          6f4be778  00000000  

如您所见,大多数可用的回溯甚至不在我自己的代码中。我正在开发具有开箱即用操作系统的开发人员版 HTC One,使用 NDK 的 8e 版并针对 android-10 构建,尽管 android-15 也不例外。我正在使用工具链 v4.7,gnustl_static STL 和我的 C++ 标志是:

-std=c++11 -g -pthread -DPROFILE -D__STRICT_ANSI__ -DdSINGLE -Wall -Wextra -Wfatal-errors -fno-rtti -fno-exceptions

我将如何获得更长的(最好是完整的)回溯?

4

3 回答 3

1

debuggerd 堆栈跟踪机制使用异常展开机制来向上遍历树。这是通过 gcc-funwind-tables参数启用的。

gdb 忽略这些并使用自己的机制,该机制依赖于反汇编代码来确定返回值在堆栈中的位置。这通常适用于 gcc 生成的代码,但可能会让人感到困惑。有时 gdb 或 debuggerd 将能够解码另一个无法解码的堆栈跟踪。

(编辑:更多注释)

基本问题是编译器被配置为生成不使用帧指针的代码。调用者将返回地址放入 LR 寄存器,完成后被调用函数跳转到该地址。LR 是一个通用寄存器,因此通常会将其溢出到堆栈并在返回之前将其恢复。遍历堆栈的代码需要确定它是否被溢出,如果是,那么它在堆栈上的什么位置可以找到。

出于某种原因,debuggerd 似乎不认为它可以遍历堆栈更远。一个原因是缺少展开信息。

于 2013-07-15T17:13:07.100 回答
1

您可以使用 gdb 在 android 上进行本机应用程序调试,请参阅 Generate core dump in android

这可以为您提供更多信息,而不仅仅是堆栈跟踪。

于 2013-07-14T01:08:09.093 回答
0

答案似乎是升级到 Android 4.3。我的手机今天收到了更新(自定义 HTC 版本推出到开发者版设备),转储到系统日志的回溯现在显示完整堆栈。然而,正如@user1034749 所建议的那样,掌握 GDB 是一个很好的选择,具有许多额外的好处。

于 2013-09-26T16:41:17.750 回答