我正在使用NDK开发Android应用程序。不幸的是,我在最近写的一些代码上遇到了段错误。我已经尝试让ndk-gdb工作多年了,但它根本不起作用(我得到一个段错误,它在程序中完全不相关的部分中断。堆栈也完全损坏。它也不会破坏在我设置的任何断点上......)。所以我决定看一下程序段错误时得到的奇怪输出。
我在Linux上编写通用C ++程序时已经看过了,但我不知道它叫什么,或者如何建设性地使用它:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/nakasi/grouper:4.2.2/JDQ39/573038:user/release-keys'
Revision: '0'
pid: 23369, tid: 23369, name: xxx.xxx >>> com.xxx.xxx <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 22e1ee54
r0 beddee50 r1 00003e99 r2 00003e99 r3 22e1ee54
r4 620b1e78 r5 4007e010 r6 00000004 r7 40099de4
r8 beddf658 r9 40099ddc sl 4007e020 fp beddeda4
ip beddee50 sp bedded88 lr 653c7c64 pc 653c8e64 cpsr 80000010
...
backtrace:
#00 pc 00006e64 /data/app-lib/com.xxx.xxx-1/libxxx.so (void anotherFunction<int>(int*, int, int, int&, int)+196)
#01 pc 00005c60 /data/app-lib/com.xxx.xxx-1/libxxx.so (aFunction(AStruct*, int&, int*, int&, unsigned short const*, int)+856)
#02 pc 000060c4 /data/app-lib/com.xxx.xxx-1/libxxx.so (Java_com_xxx_xxx_ClassName_f66+1072)
#03 pc 0001e290 /system/lib/libdvm.so (dvmPlatformInvoke+112)
#04 pc 0004d411 /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+396)
#05 pc 0004f56f /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+174)
#06 pc 000276a0 /system/lib/libdvm.so
#07 pc 0002b57c /system/lib/libdvm.so (dvmInterpret(Thread*, Method const*, JValue*)+184)
#08 pc 0005ff07 /system/lib/libdvm.so (dvmInvokeMethod(Object*, Method const*, ArrayObject*, ArrayObject*, ClassObject*, bool)+374)
#09 pc 000677e1 /system/lib/libdvm.so
...
stack:
bedded48 c0000000
bedded4c beddf508 [stack]
bedded50 00000003
bedded54 00000100
...其次是各种寄存器附近的存储器
这被称为核心转储吗?
我对程序崩溃的条件并不特别感兴趣。如何将函数名称和指令偏移从回溯转换为我可以使用的行号?从那里我可以打印调试。到目前为止,我基本上已经用android等效的printf二进制搜索我的代码...而且这真的,真的,真的很慢......
干杯
答案 0 :(得分:1)
构建时,请使用可能为您提供有关回溯的更多信息的ndk-build NDK_DEBUG=1
。
如果这没有神奇的帮助,您可以使用addr2line
(您仍然需要使用符号构建)。
addr2line <addr> -e <filename>
在你的情况下,你应该得到类似
的东西$addr2line 0x6e64 -e libxxx.so
XXX.c:406
如果您的libxxx.so
未映射到0x0
,则此处可能存在一个问题,那么所有地址都将偏移到其他某个基值。但是,你的地址看起来很小,所以它可能工作,甚至可能是内核直接打印正确的值(从指针值中减去映射的地址,并在日志中正确打印地址)。