How to use addr2line in Android
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.
How do I use addr2line for Android?
Use ndk-stack
instead. Save your native log crash in a file, says log.txt and then use
$NDK_HOME/ndk-stack -sym $PROJECT_HOME/obj/local/armeabi -dump log.txt
of course, your native library has to be compiled with the debug symbols.
From the doc:
'ndk-stack' is a simple tool that allows you to filter stack traces as
they appear in the output of 'adb logcat' and replace any address inside a
shared library with the corresponding "source-file : line-number" values.
Addr2line 64bit tool
Found the required utility for 64 bits.
The 32-bit utility was located here
C: \ Program Files \ Unity \ Hub \ Editor \ 2019.2.19f1 \ Editor \ Data \ PlaybackEngines \ AndroidPlayer \ NDK \ toolchains \ arm-linux-androideabi-4.9 \ prebuilt \ windows-x86_64 \ bin \ arm-linux-androideabi- addr2line.exe
And 64 bits are here
C: \ Program Files \ Unity \ Hub \ Editor \ 2019.2.19f1 \ Editor \ Data \ PlaybackEngines \ AndroidPlayer \ NDK \ toolchains \ aarch64-linux-android-4.9 \ prebuilt \ windows-x86_64 \ bin \ aarch64-linux-android- addr2line.exe
And it's called a little differently - aarch64-linux-android-addr2line. Despite the fact that the name of the utility does not contain the word arm, it successfully decrypts stacktraces from under arm64-v8 and normally perceives characters for arm64-v8
The rest of the commands are the same, i.e.
./aarch64-linux-android-addr2line -f -C -e "C: \ Program Files \ Unity \ Hub \ Editor \ 2019.2.19f1 \ Editor \ Data \ PlaybackEngines \ AndroidPlayer \ NDK \ toolchains \ arm-linux-androideabi- 4.9 \ prebuilt \ windows-x86_64 \ bin \ arm64-v8a \ libunity.sym.so "00000000001f6f34
Returns normal stack trace for memory address 00000000001f6f34
arm-eabi-addr2line don't show line number
Do you have debugging symbols in your .so? You should also disable optimization (-O0) and inline functions (-fno-inline)
frida - How to translate native backtrace to use with addr2line tool
Below steps (e.g. libc.so)
- Get library base address:
0xac0ad000 <- Module.findBaseAddress("libc.so")
- Get backtrace
Thread.backtrace(thz.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n
");
Sample output:
0xac151ed7 libc.so!fopen64+0x2e
3.Substract baseAddr to get PC value
#pc 0x000a4ed7 <- 0xac151ed7 - 0xac0ad000
- Addr2line with PC value
$ addr2line -f -C -i -e
symbols/apex/com.android.runtime/lib/bionic/libc.so 0x000a4ed7
open(char const*, int pass_object_size1, unsigned short)
bionic/libc/include/bits/fortify/fcntl.h:74 fopen
bionic/libc/stdio/stdio.cpp:256
How to get Crash Point in Java code
You can't get the stack trace for code written in the Java programming language out of a native stack trace in the Dalvik VM, for the simple reason that Dalvik uses different pieces of memory for the native and managed stacks. (I believe it's possible to get it from Art crashes, because Art uses a shared stack, but can't say for certain.)
The fault address suggests a null pointer dereference, and the call through jniGetFDFromFileDescriptor()
indicates file activity. You can see the source code for that method here. I would guess it's calling GetIntField
on a null object, which would match with your suspicions.
Enabling CheckJNI may help -- if the JNI checker spots a problem, it will usually dump the current thread's stack trace to the log file before killing the VM.
How do I get android NDK detail crash reports?
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
How can I add a '.so' library in my android project
after making your native c code and header file browse to the root directory of your project and run ndk-build command.That will generate the .so file and then place it inside your project/libs folder
Related Topics
Error Android Emulator Gets Killed in Android Studio
How to Adjust Layout When Soft Keyboard Appears
How to Add Sha-1 to Android Application
Published App on Play Store Can't Communicate with Google Maps API and Facebook API
How to Import Existing Android Project into Eclipse
How to Build an APK File in Eclipse
Android Turn On/Off Wifi Hotspot Programmatically
Unable Instantiate Android.Gms.Maps.Mapfragment
How to Detect Shake Event with Android
Error:(6, 0) Gradle Dsl Method Not Found: 'Google()'
Android Spinner with Multiple Choice
Unsupportedoperationexception: Can't Convert to Dimension: Type=0X1
How to Remove Application from App Listings on Android Developer Console
Could Not Find Com.Android.Tools.Build:Gradle:3.0.0-Alpha1 in Circle Ci