C ++ Segfault输出

时间:2013-06-26 03:51:50

标签: android c++ android-ndk segmentation-fault stack

我正在使用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二进制搜索我的代码...而且这真的,真的,真的很慢......

干杯

1 个答案:

答案 0 :(得分:1)

构建时,请使用可能为您提供有关回溯的更多信息的ndk-build NDK_DEBUG=1

如果这没有神奇的帮助,您可以使用addr2line(您仍然需要使用符号构建)。

addr2line <addr> -e <filename>

在你的情况下,你应该得到类似

的东西
$addr2line 0x6e64 -e libxxx.so
XXX.c:406

如果您的libxxx.so未映射到0x0,则此处可能存在一个问题,那么所有地址都将偏移到其他某个基值。但是,你的地址看起来很小,所以它可能工作,甚至可能是内核直接打印正确的值(从指针值中减去映射的地址,并在日志中正确打印地址)。