C++ Segfault output

C++ Segfault output

本文关键字:output Segfault C++      更新时间:2023-10-16

我正在使用NDK开发一个android应用程序。不幸的是,我最近写的一些代码出现了segfault。我试着让ndk-gdb工作了很长时间,但它根本不起作用(我得到了一个segfault,它在程序的一个完全不相关的部分中断了。堆栈也完全损坏了。它也不会在我设置的任何断点中断…)。所以我决定看看程序segfault时我得到的奇怪输出。

我在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 

然后是各种寄存器附近的存储器

这叫做堆芯转储吗?

我对程序崩溃的条件不是特别感兴趣,只是它在哪里崩溃了。如何将回溯的函数名和指令偏移量转换为可以使用的行号?从那里我可以打印调试。到目前为止,我基本上一直在用相当于printf的android二进制搜索我的代码。。。这真的,真的,非常慢。。。

干杯

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

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

addr2line <addr> -e <filename>

在你的情况下,你应该给你一些类似的东西

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

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