C++ Segfault输出

3
我正在使用NDK开发安卓应用,但最近编写的一些代码出现了段错误。我尝试了很长时间让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 进行二进制搜索我的代码......而这真的、真的、非常慢......

干杯


https://dev59.com/veo6XIcBkEYKwwoYTzAw#2480465 - fadden
1个回答

1
在构建时,请使用ndk-build NDK_DEBUG=1,这可能会为您提供更多有关回溯的信息。
如果这并没有神奇地帮助你,你可以使用addr2line(仍需要使用符号构建)。
addr2line <addr> -e <filename>

在您的情况下,您应该得到类似于以下内容:
$addr2line 0x6e64 -e libxxx.so
XXX.c:406

如果你的libxxx.so没有映射到0x0,那么所有地址都会偏移一些其他基础值。然而,你的地址看起来足够小,所以它可能会工作,甚至内核可能直接打印正确的值(从指针值中减去映射地址并在日志中正确地打印地址)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接