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!
Related
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 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
I have written an Android app entirely in C using the new native_app_glue code that comes with the latest Android NDK. It's all working fine except one strange thing. When I close down my app and start it again, I get a crash in my .so shared object. I used addr2line to find out the function that crashes, but it just doesn't make any sense because it's always a different function that causes the crash and of course, the first time it worked fine, too. So it must be something else.
Does anybody have an idea what could cause this behaviour? As I said, the behaviour is like this:
1) First time start --> app always works fine
2) Second time start --> app crashes
3) Third time start --> app works fine again
4) Fourth time start --> app crashes again
5) Fifth time start --> works fine again
6) Sixth time --> crash
and so on and so forth.
I don't know what's wrong there. Maybe my app doesn't get shut down correctly? But I'm getting and handling both term messages (APP_CMD_TERM_WINDOW and APP_CMD_DESTROY). I've really got no clue what's wrong there...
Thanks for help!
Edit: Here's the crash log:
I/DEBUG ( 31): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG ( 31): Build fingerprint: 'generic/sdk/generic:2.3.1/GSI11/93351:eng/test-keys'
I/DEBUG ( 31): pid: 1105, tid: 1114 >>> com.example.testapp <<<
I/DEBUG ( 31): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000058
I/DEBUG ( 31): r0 8382746d r1 00000000 r2 00000058 r3 00000058
I/DEBUG ( 31): r4 00000000 r5 8382746d r6 00242920 r7 00000554
I/DEBUG ( 31): r8 00245150 r9 001ec8e0 10 839651dc fp 00000000
I/DEBUG ( 31): ip 839654e0 sp 435fc2b0 lr 8381c78f pc 83861858 cpsr 00000030
I/DEBUG ( 31): #00 pc 00061858 /data/data/com.example.testapp/lib/libtestapp.so
I/DEBUG ( 31): #01 pc 0001c78a /data/data/com.example.testapp/lib/libtestapp.so
I/DEBUG ( 31): #02 pc 0001d7d4 /data/data/com.example.testapp/lib/libtestapp.so
I/DEBUG ( 31): #03 pc 000ab1fa /data/data/com.example.testapp/lib/libtestapp.so
I/DEBUG ( 31): #04 pc 000fc9e2 /data/data/com.example.testapp/lib/libtestapp.so
I/DEBUG ( 31): #05 pc 00011a7c /system/lib/libc.so
I/DEBUG ( 31): #06 pc 00011640 /system/lib/libc.so
It's possible that your library is still loaded when you try to restart your app. I know that loading the same lib twice will cause a crash.
the solution that I go with is in the same activity that you load the lib, override OnDestroy with a second same loadlibrary. that will crash the native side when the activity finishes (probably best to load your library on the launcher activity). that way you'll have a clean slate when you restart your app.
From your dump it seems that the problem is not in any native_app_glue call but in your source code.
Initially, if it's crashing calling a third party function, most probably, you would have, at least, one libc.so reference in your back trace but, instead, the first reference is to your own library. Can you, please, post the stack information? without seen the source code, I would bet for some kind of NULL pointer reference.
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