I am stuck with my app, as I am unable to debug as it is a multithreaded one and crashes with error SIGSEGV. I get lot of information from LogCat, which gives me addresses in my native library. It would be helpful if I could convert these addresses into my code.
Does anybody have any idea how to use addr2line, which is provided with android-ndk?
Let's say that logcat show you the following crash log (this is from one of my projects):
I/DEBUG ( 31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 31): Build fingerprint: 'generic/sdk/generic:2.3/GRH55/79397:eng/test-keys'
I/DEBUG ( 31): pid: 378, tid: 386 >>> com.example.gltest <<<
I/DEBUG ( 31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
I/DEBUG ( 31): r0 001dbdc0 r1 00000001 r2 00000000 r3 00000000
I/DEBUG ( 31): r4 00000000 r5 40a40000 r6 4051a480 r7 42ddbee8
I/DEBUG ( 31): r8 43661b24 r9 42ddbed0 10 42ddbebc fp 41e462d8
I/DEBUG ( 31): ip 00000001 sp 436619d0 lr 83a12f5d pc 8383deb4 cpsr 20000010
I/DEBUG ( 31): #00 pc 0003deb4 /data/data/com.example.gltest/lib/libnativemaprender.so
I/DEBUG ( 31): #01 pc 00039b76 /data/data/com.example.gltest/lib/libnativemaprender.so
I/DEBUG ( 31): #02 pc 00017d34 /system/lib/libdvm.so
Look at the last 3 lines; this is your callstack. 'pc' is the program counter, and the pc for stack frame #00 gives you the address where the crash occurred. This is the number to pass to addr2line.
I'm using NDK r5, so the executable I'm using is located at $NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin; make sure that is in your $PATH. The command to use looks like
arm-linux-androideabi-addr2line -C -f -e obj/local/armeabi/libXXX.so <address>
Or, for the case above:
arm-linux-androideabi-addr2line -C -f -e obj/local/armeabi/libnativemaprender.so 0003deb4
Which gives you the location of the crash.
Note:
The -C flag is to demangle C++ code
Use the .so file under
obj/local/armeabi, since this is the
non-stripped version
Also, when using NDK r5 with a 2.3 AVD, it is actually possible to debug multithreaded code.
There's an easier way to do this now (ndk-r7). Check out the ndk-stack command. The docs are in you_android_ndk_path/docs/NDK-STACK.html
Related
I am debugging a huge NDK project in Android Studio, the app crashes at semingly random times with message similar to
A/libc: Fatal Signal 11 (SIGSEGV), code 1, fault addr 0x30 in fid 22993 (Thread-99505)
The numbers are different at times but the error is similar, and sometimes the Run tab in Android studio doesn't even show any error at all and the program just crashes with the message Application terminated
By looking around I have found that android should generate some kind of crash log similar to ones shown here
https://source.android.com/devices/tech/debug/native-crash
But I do not understand how to get them, or whether there is some setting in Android Studio that allows me to view them
How do I get crash reports like these from Android Studio?
Android Studio version 3.0.1 in Apple macbook
Instead of the Run tab, look at the Logcat. Don't set the filter to your app only. There is a good chance that you will see a stack trace, like
I/DEBUG ( 31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 31): Build fingerprint: 'generic/google_sdk/generic/:2.2/FRF91/43546:eng/test-keys'
I/DEBUG ( 31): pid: 351, tid: 351 >>> /data/local/ndk-tests/crasher <<<
I/DEBUG ( 31): signal 11 (SIGSEGV), fault addr 0d9f00d8
I/DEBUG ( 31): r0 0000af88 r1 0000a008 r2 baadf00d r3 0d9f00d8
I/DEBUG ( 31): r4 00000004 r5 0000a008 r6 0000af88 r7 00013c44
I/DEBUG ( 31): r8 00000000 r9 00000000 10 00000000 fp 00000000
I/DEBUG ( 31): ip 0000959c sp be956cc8 lr 00008403 pc 0000841e cpsr 60000030
I/DEBUG ( 31): #00 pc 0000841e /data/local/ndk-tests/crasher
I/DEBUG ( 31): #01 pc 000083fe /data/local/ndk-tests/crasher
I/DEBUG ( 31): #02 pc 000083f6 /data/local/ndk-tests/crasher
I/DEBUG ( 31): #03 pc 000191ac /system/lib/libc.so
I/DEBUG ( 31): #04 pc 000083ea /data/local/ndk-tests/crasher
I/DEBUG ( 31): #05 pc 00008458 /data/local/ndk-tests/crasher
I/DEBUG ( 31): #06 pc 0000d362 /system/lib/libc.so
I/DEBUG ( 31):
Android NDK includes a command ndk-stack that can help match the addresses with actual source files of your code, which is based on the addr2line utility in NDK toolchain.
Further instructions for understanding the stack trace: https://developer.android.com/studio/debug/stacktraces
From comments:
You may find the 'unstripped' libraries under app/build/intermediates/transforms/mergeJniLibs
I have a hello world C++ application that links with many 3rdpart and home-made libraries. It crashes immediately when trying to load it, with Segmentation Fault.
The same code, with the same dependencies, all compiled for Linux - runs successfully.
How can I start to debug it?
What could be the reason?
Edit: This is what logcat prints:
F/libc ( 8129): Fatal signal 11 (SIGSEGV), code 128, fault addr 0x0 in tid 8129 (HelloWorldApp) I/DEBUG ( 2876): *** *** *** *** *** ***
*** *** *** *** *** *** *** *** *** *** I/DEBUG ( 2876): Build fingerprint: 'Intel/cht_hr/cht_hr:5.1.1/LMY47Z/LS0000037:userdebug/test-keys' I/DEBUG ( 2876): Revision: '0' W/NativeCrashListener( 3194): Couldn't find ProcessRecord for pid 8129 I/DEBUG ( 2876): ABI: 'x86' I/DEBUG ( 2876): pid: 8129, tid: 8129, name: HelloWorldApp >>> ./StaticImageOR <<< E/DEBUG ( 2876): AM write failure (32 / Broken pipe) I/DEBUG ( 2876): signal 11 (SIGSEGV), code 128 (SI_KERNEL), fault addr 0x0 I/DEBUG ( 2876): eax ff84cadc ebx f32b7c6c ecx 00000010 edx 00000000 I/DEBUG ( 2876): esi f32c6610 edi 00000000 I/DEBUG ( 2876): xcs 00000023 xds 0000002b xes 0000002b xfs 00000000 xss 0000002b I/DEBUG ( 2876): eip f2600cfb ebp ff84c6dc esp ff84c5f4 flags 00010246 I/DEBUG ( 2876): I/DEBUG ( 2876): backtrace: I/DEBUG ( 2876): #00 pc 0062fcfb /system/lib/libcommander.so I/DEBUG ( 2876): #01 pc 0017651f /system/lib/libcommander.so I/DEBUG ( 2876): #02 pc 00001fcb /system/bin/linker (__dl__ZN6soinfo16CallConstructorsEv.part.23+1275) I/DEBUG ( 2876):
#03 pc 00001c26 /system/bin/linker (__dl__ZN6soinfo16CallConstructorsEv.part.23+342) I/DEBUG ( 2876):
#04 pc 00001c26 /system/bin/linker (__dl__ZN6soinfo16CallConstructorsEv.part.23+342) I/DEBUG ( 2876):
#05 pc 00008706 /system/bin/linker (__dl___linker_init+4998) I/DEBUG ( 2876): #06 pc 00009e0e /system/bin/linker (__dl__start+30) I/DEBUG ( 2876): I/DEBUG ( 2876): Tombstone written to: /data/tombstones/tombstone_02
So I undersatnd the problem is in libcommander loading.
How to continue with this?
Thanks!
The easiest way is to run your application under debugger, then most recent android studio is really good at debugging c++ code. For instructions how to debug jni code, find Create Hello-JNI with Android Studio in google code labs.
Other solution is to look into logcat, you might find there reason for the crash. For example you can find lines like
I/DEBUG ( 8704): signal 11 (SIGSEGV), fault addr deadbaad
...
...
which will contain call stack for the location where crash happend. With that information you can use ndk-stack - tool (see here ndk-stack), to turn frame addresses into symbolic names.
Android will put into logcat other warnings/jni error that might help you find a location of the problem.
I have a library in Haskell that I have generated wrappers for via FFI and Swig. I have also managed to cross-compile a shared library that I can load from Java. The wrapped library contains some functions and input/output types for these.
On my Arch machine I am able to use my library from Java. However, when I now tried it out on Android, it segfaults. After some investigation, It seems that if the input object has no fields, it sometimes work. I think it's a problem with data marshalling. However it's hard to debug. In the crash log I find this
W/linker ( 4783): libAPIsJava.so has text relocations. This is wasting memory and prevents security hardening. Please fix.
and this
--------- beginning of crash
F/libc ( 4783): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x200019 in tid 4783 (api.flic.io.api)
I/Icing ( 1689): Indexing 17F83E8EEF17AFFA030207AF16B79084CE236092 from com.google.android.googlequicksearchbox
I/DEBUG ( 357): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 357): Build fingerprint: 'google/shamu/shamu:5.1/LMY47D/1743759:user/release-keys'
I/DEBUG ( 357): Revision: '33696'
I/DEBUG ( 357): ABI: 'arm'
I/DEBUG ( 357): pid: 4783, tid: 4783, name: api.flic.io.api >>> app.api.flic.io.api <<<
I/DEBUG ( 357): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x200019
I/DEBUG ( 357): r0 af2033d4 r1 af2033d0 r2 00000000 r3 00200018
I/DEBUG ( 357): r4 a2bbf950 r5 af2033dc r6 af2029a0 r7 af202fff
I/DEBUG ( 357): r8 a2af06b0 r9 00200019 sl af2033c8 fp af2030a4
I/DEBUG ( 357): ip b6e627dc sp bec8eee0 lr af2029b0 pc a0b4d248 cpsr 800d0010
I/DEBUG ( 357):
I/DEBUG ( 357): backtrace:
I/DEBUG ( 357): #00 pc 01be4248 /data/app/app.api.flic.io.api-2/lib/arm/libAPIsJava.so
However, Issuing arm-linux-androideabi-addr2line -f -e libAPIsJava.so 01be4248, the output is
$a
/tmp/ghc27404_0/ghc27404_3.bc:?
Which is not of much help. What I would really like is to run the app with valgrind, is something like that possible?
Update: I have now installed valgrind and tried to run the app. However I get
valgrind: mmap(0x108000, 42770432) failed in UME with error 22 (Invalid argument).
valgrind: this can be caused by executables with very large text, data or bss segments.
Which seems to be a no-go.
It turned out the problem was that my cross compile toolchain (https://github.com/neurocyte/ghc-android) has a bug in its hsc2hs script. It's implemented as a wrapper that calls /usr/bin/hsc2hs with some flags. However, it wasn't using the --cc and --ld flag, so the resulting .hs file targeted my build host. By adding these flags, everything works great!
I compiled v8 for ARM and it loads fine on the majority of arm6/7 phones. Some specific devices like the HTC Wildfire S crash when loading the native library.
This is the SIGILL (invalid instruction) I get:
31-31/? I/DEBUG﹕ *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
31-31/? I/DEBUG﹕ Build fingerprint: 'generic/sdk/generic/:2.2/FRF91/43546:eng/test-keys'
31-31/? I/DEBUG﹕ pid: 312, tid: 312 >>> org.myapp <<<
31-31/? I/DEBUG﹕ signal 4 (SIGILL), fault addr 81494f98
31-31/? I/DEBUG﹕ r0 00000001 r1 00000003 r2 81494f8e r3 81494f8c
31-31/? I/DEBUG﹕ r4 8198a26c r5 00000003 r6 00000004 r7 00000000
31-31/? I/DEBUG﹕ r8 42189eac r9 00000374 10 0000ce04 fp bef6765c
31-31/? I/DEBUG﹕ ip 8124695c sp bef67658 lr b0001169 pc 81494f98 cpsr 80000010
31-31/? I/DEBUG﹕ #00 pc 00494f98 /data/data/org.myapp/lib/libjv8.so
I could use ndk-stack to get the specific line in v8 that's crashing, but it actually refers to a macro so I don't know which specific instruction is being executed.
I tried to connect to the device with gdb-server, but it doesn't give me more details about the instruction:
Program received signal SIGILL, Illegal instruction.
0x81494f98 in ?? ()
So I'm a bit lost. Is there a way to translate 0x81494f98 to a specific ARM instruction?
Thanks to #ChrisStratton, this is how I was able to find the specific ARM instructions that causes a SIGILL:
$ arm-whatever-objdump -d <lib_path> | grep <pc_address>
or in my case:
$ arm-whatever-objdump -d libjv8.so | grep 494f98
It produced the following line:
494f98: e30f1fff movw r1, #65535 ; 0xffff
I am looking for a native crash in my application but i cant find a tool that help me to translate the address to the function names in my library i saw this post : how to use addr2line but it seems that only works when you have a trace like this :
I/DEBUG ( 31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 31): Build fingerprint: 'generic/sdk/generic:2.3/GRH55/79397:eng/test-keys'
I/DEBUG ( 31): pid: 378, tid: 386 >>> com.example.gltest <<<
I/DEBUG ( 31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
I/DEBUG ( 31): r0 001dbdc0 r1 00000001 r2 00000000 r3 00000000
I/DEBUG ( 31): r4 00000000 r5 40a40000 r6 4051a480 r7 42ddbee8
I/DEBUG ( 31): r8 43661b24 r9 42ddbed0 10 42ddbebc fp 41e462d8
I/DEBUG ( 31): ip 00000001 sp 436619d0 lr 83a12f5d pc 8383deb4 cpsr 20000010
I/DEBUG ( 31): #00 pc 0003deb4 /data/data/com.example.gltest/lib/libnativemaprender.so
I/DEBUG ( 31): #01 pc 00039b76 /data/data/com.example.gltest/lib/libnativemaprender.so
I/DEBUG ( 31): #02 pc 00017d34 /system/lib/libdvm.so
as you can see in the last 3 lines the library of your application is there : ibnativemaprender.so
and only if your library appear there the addr2line app will work
but in my trace i have this :
I/DEBUG (16251): #00 pc 000161c0 /system/lib/libc.so
I/DEBUG (16251): #01 lr afd196f1 /system/lib/libc.so
and my library is not show there until later :
/DEBUG (16251): stack:
I/DEBUG (16251): 46f0c818 afd426a4
I/DEBUG (16251): 46f0c81c 000b7290
I/DEBUG (16251): 46f0c820 00000afa
I/DEBUG (16251): 46f0c824 afd187b9 /system/lib/libc.so
I/DEBUG (16251): 46f0c828 afd42644
I/DEBUG (16251): 46f0c82c afd467c4
I/DEBUG (16251): 46f0c830 00000000
I/DEBUG (16251): 46f0c834 afd196f1 /system/lib/libc.so
I/DEBUG (16251): 46f0c838 00000001
I/DEBUG (16251): 46f0c83c 46f0c86c
I/DEBUG (16251): 46f0c840 81b6a4a0 /data/data/com.android.ANMP/lib/mylib.so
so is there a tool that can help me? or a different way to use addr2line?
No, not really. To do that you need to perform the search manually.
Manually, there are a three options:
Add debug prints to find out where and when it happens
Use IDA pro, (which is very expensive tool), load your library into it and look for the address 81b6a4a0, try to figure out which function it is. If you compile with debug symbols it should be easy enough.
Find the base address of your library, use objdump (from the NDK toolchain) to find what's in the address 81b6a4a0 (after removing base address from it).
In both last ways, if you don't find anything helpful, pull libc.so and libdvm.so from the device using adb and try to find what are the functions that appears in the stack trace, then check where do you call those functions in your code.
take a look at this. I have not yet found the time to try, so tell if if worked for you
You can use GDB to get stack traces. If you have a rooted phone or use the emulator you can enable core dumps. Then you can use GDB to examine the core dumps.
See this question for setting up GDB in Eclipse:
android how to use ndk gdb with a pure native executable