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.
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 an Android app published on Google Play that is implemented in large part in RenderScript (native, not using support library APIs). The app sometimes seems to crash in libCB.so. Crash rate is 1.40% as reported by the Google Play Console.
The crash seems to occur in all Android versions from 6.0 to 8.1 (API levels 23–27). I haven't received a report from older versions even though the app's minSdkVersion is 18 (Android 4.3). All kinds of devices from various manufacturers seem to be affected, both cheap no-name products as well as hi-end devices.
The app uses the Camera 1 API to capture frames from a live preview video (setPreviewCallbackWithBuffer). The PreviewCallback sends the frame data through a series of RenderScripts that process that input. At two stages the processed data is then also sent to two different TextureViews. I can provide more details if necessary.
I'm not sure what causes the problem since I was not able to reproduce it locally on any of my own test devices.
Does anyone know what might be the cause of this issue or if there is any workaround?
Here's a typical backtrace:
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'Xiaomi/land/land:6.0.1/MMB29M/V9.2.2.0.MALMIEK:user/release-keys'
Revision: '0'
ABI: 'arm'
pid: 17840, tid: 17862, name: JNISurfaceTextu >>> com.app.my <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x38
r0 00000000 r1 00000000 r2 00000002 r3 00000000
r4 00000000 r5 ef8e0a38 r6 00000002 r7 00000000
r8 ab06e808 r9 00000000 sl 00000000 fp ef8e0c30
ip e044d8f8 sp ef8e09f8 lr e03ac9b3 pc e03ac89c cpsr 800f0030
backtrace:
#00 pc 0003189c /system/vendor/lib/libCB.so (cl_mem_non_local_event_cache_state_transition+15)
#01 pc 000319af /system/vendor/lib/libCB.so (cl_mem_grant_access_to_device_internal+58)
#02 pc 00031ae5 /system/vendor/lib/libCB.so (cb_grant_access_to_device+84)
#03 pc 0000eb61 /system/vendor/lib/librs_adreno.so
#04 pc 0000683b /system/vendor/lib/librs_adreno.so
#05 pc 000068a1 /system/vendor/lib/librs_adreno.so
#06 pc 00007f33 /system/vendor/lib/librs_adreno.so
#07 pc 00009707 /system/vendor/lib/librs_adreno.so
#08 pc 00009ee5 /system/vendor/lib/librs_adreno.so
#09 pc 000088f5 /system/vendor/lib/librs_adreno.so (rsdVendorScriptInvokeForEach3+236)
#10 pc 00019bf9 /system/vendor/lib/libRSDriver_adreno.so (_Z29rsdVendorInvokeForEachWrapperPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall+84)
#11 pc 00019cfb /system/vendor/lib/libRSDriver_adreno.so (_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall+38)
#12 pc 0002ebf3 /system/lib/libRS.so (_ZN7android12renderscript7ScriptC10runForEachEPNS0_7ContextEjPPKNS0_10AllocationEjPS4_PKvjPK12RsScriptCall+294)
#13 pc 00033e41 /system/lib/libRS.so (_ZN7android12renderscript22rsp_ScriptForEachMultiEPNS0_7ContextEPKvj+48)
#14 pc 000311ff /system/lib/libRS.so (_ZN7android12renderscript8ThreadIO16playCoreCommandsEPNS0_7ContextEi+338)
#15 pc 00023d27 /system/lib/libRS.so (_ZN7android12renderscript7Context10threadProcEPv+646)
#16 pc 0004185b /system/lib/libc.so (_ZL15__pthread_startPv+30)
#17 pc 000192a5 /system/lib/libc.so (__start_thread+6)
Well, we had a similar issue with opencv c++ code compiled for Android.
Our mistake was setting timers which call jni functions and forgetting them to purge afterwards. Eventually garbage collector wasn't able to follow the references which causes memory leak. So our app used to crash unless it was killed by the user for like, maybe a whole day.
Are you setting timers anywhere in your code?
Or are you keeping the track of the threads (if anyone of them exists) which call jni functions?
You might want to check this if you are interested: Timer::purge()
Are the crashes mostly related to libCB.so? If so, it could be a bug in Qualcomm RenderScript driver. I suspect it only affects certain SOC.
Please file a bug in https://buganizer.corp.google.com/issues?q=componentid:192772, and attach the potential steps to reproduce this.
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 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 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