3

I'm working on an android app using the NDK. Unfortunately, I'm getting segfaults on some code I've recently written. I've tried getting ndk-gdb working for ages, but it doesn't work at all (I get a segfault and it breaks in a totally unrelated part of the program. The stack is also completely corrupt. It also won't break on any breakpoints I set...). So I've decided to look at the strange output I get when a program segfaults.

I've seen it when writing general C++ programs on Linux, but I don't know what its called, or how to use it constructively:

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
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 

...followed by memory near various registers

Is this called a core dump?

I'm not particularly interested in the conditions in which the program crashed, just where it did. How do I convert the function name and instruction offset from the backtrace into a line number I can use? From there I can just print debug. Up to now, I've basically been binary searching my code with the android equivalent of printf... And that's really, really, REALLY slow...

Cheers

Raghav Sood
  • 81,899
  • 22
  • 187
  • 195
AStupidNoob
  • 1,980
  • 3
  • 23
  • 35
  • http://stackoverflow.com/questions/2314273/get-function-names-from-call-stack/2480465#2480465 – fadden Jun 26 '13 at 22:34

1 Answers1

1

When building, use ndk-build NDK_DEBUG=1 that might give you more information on backtrace.

If that doesn't magically help, you can use addr2line (which you'll still need to build with symbols).

addr2line <addr> -e <filename>

In your case you should get you something like

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

One possible problem here if your libxxx.so isn't mapped at 0x0, then all the addresses would be offset to some other base value. However your addresses look small enough so it might work or may be even kernel prints the right values directly (subtracting the mapped addresses from pointer values and correctly printing addresses on log).

auselen
  • 27,577
  • 7
  • 73
  • 114