在我们平时出现ndk异常,光是看错误是看不懂的,比如以下错误:
A/libc: stack corruption detected (-fstack-protector)
A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 9466 (shixin.ndkdemo)
2018-12-02 22:27:41.096 2670-2990/com.google.android.gms I/Icing: Usage reports ok 0, Failed Usage reports 0, indexed 0, rejected 0, imm upload false
I/crash_dump32: obtaining output fd from tombstoned
I//system/bin/tombstoned: received crash request for pid 9466
I/crash_dump32: performing dump of process 9466 (target tid = 9466)
A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
A/DEBUG: Build fingerprint: 'google/sdk_gphone_x86/generic_x86:8.0.0/OSR1.170901.056/4497355:userdebug/dev-keys'
A/DEBUG: Revision: '0'
A/DEBUG: ABI: 'x86'
A/DEBUG: pid: 9466, tid: 9466, name: shixin.ndkdemo >>> shixin.ndkdemo <<<
A/DEBUG: signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
A/DEBUG: Abort message: 'stack corruption detected (-fstack-protector)'
A/DEBUG: eax 00000000 ebx 000024fa ecx 000024fa edx 00000006
A/DEBUG: esi 000024fa edi bfa41188
A/DEBUG: xcs 00000073 xds 0000007b xes 0000007b xfs 0000003b xss 0000007b
A/DEBUG: eip affadac4 ebp bfa411a8 esp bfa4113c flags 00000296
A/DEBUG: backtrace:
//报错起始地址
A/DEBUG: #00 pc 00000ac4 [vdso:affad000] (__kernel_vsyscall+16)
A/DEBUG: #01 pc 00075b3c /system/lib/libc.so (tgkill+28)
A/DEBUG: #02 pc 0001f04e /system/lib/libc.so (abort+110)
A/DEBUG: #03 pc 0002720e /system/lib/libc.so (__libc_fatal+46)
A/DEBUG: #04 pc 00072f63 /system/lib/libc.so (__stack_chk_fail+35)
A/DEBUG: #05 pc 00008ec2 /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/lib/x86/libmy_native_lib.so (_Z12arrayPointerv+194)
A/DEBUG: #06 pc 000090ce /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/lib/x86/libmy_native_lib.so (Java_shixin_ndkdemo_MainActivity_testCrash+46)
A/DEBUG: #07 pc 000096f8 /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/oat/x86/base.odex (offset 0x9000)
A/DEBUG: #08 pc 00059fff [anon:libc_malloc:afd00000]
A/DEBUG: #09 pc 01244a67 /dev/ashmem/dalvik-main space (region space) (deleted)
A/DEBUG: #10 pc 8bc3b28f <unknown>
A/DEBUG: #11 pc 80c1c541 <unknown>
A/DEBUG: #12 pc 0d3fffff /dev/ashmem/dalvik-main space (region space) (deleted)
咱们只能看到报错的起始地址:00000ac4,看不到具体对应的源代码路径,不能像java那样方便查看,很是头疼,其实也有方式看的,比如后面记录的两种。
在说这个之前,先简单说下符号表:
- 符号表:
符号表是内存地址与函数名、文件名、行号的映射表,就像咱们java离的mapping文件类似的作用,可以定位出具体源代码。平时我们自己编写ndk的时候(这里指的cmake方式),/build/intermediates/cmake/路径下生成的so都是带符号表的,所以so会比较大。当打出apk的时候,就自动trip了,去符号表,so就比较小了。官网参数DCMAKE_BUILD_TYPE有说到。
接下来看下反编译的方式:
一. add2Line 工具
- add2line工具路径:
ndk-bundle目录->toolchains->对应的abi(比如x86)->prebuild->目录->bin->文件后缀为-addr2line
- 命令方式如下:
add2line -e 带符号表的so路径 错误栈地址
咱们利用add2line -e命令来输出错误栈对应源代码信息,从调用栈一个一个查找下来,下面为查找到#06步:
./i686-linux-android-addr2line -e /Users/MyDemo/NDKDemo/app/build/intermediates/cmake/debug/obj/x86/libmy_native_lib.so 000090ce
输出:
/MyDemo/NDKDemo/app/src/main/cpp/crash_test.cpp:99
惊喜,这样就输出错误的cpp文件与行数了。
利用该工具可以使用so与错误日志中的地址来显示出源文件中的位置。
二. ndk-stack 命令
上面用add2line工具虽然可以查看,但是一个一个的查下去,很慢,效率很低,所以一般都没用那种,常用ndk-stack命令,官方使用说明点这里.
- ndk-stack路径
sdk/ndk-bundle/ndk-stack
命令方式:
- 以logcat作为输入,可即时显示出来
- 命令:参数-sym
adb logcat | ndk-stack路径 -sym 工程下abi路径(比如build/intermediates/cmake/debug/obj/armeabi)
- 使用
//这里是在ndk-stack路径下,后面是x86路径
adb logcat | ./ndk-stack -sym /Users/MyDemo/NDKDemo/app/build/intermediates/cmake/debug/obj/x86
只要一遇到错误就会输出(刚执行过缓存的错误,或者接下来复现的错误):
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Stack frame #00 pc 00000ac4 [vdso:affad000] (__kernel_vsyscall+16)
Stack frame #01 pc 00075b3c /system/lib/libc.so (tgkill+28)
Stack frame #02 pc 0001f04e /system/lib/libc.so (abort+110)
Stack frame #03 pc 0002720e /system/lib/libc.so (__libc_fatal+46)
Stack frame #04 pc 00072f63 /system/lib/libc.so (__stack_chk_fail+35)
Stack frame #05 pc 00008ec2 /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/lib/x86/libmy_native_lib.so (_Z12arrayPointerv+194): Routine arrayPointer() at /Users/shixin/Documents/MyProject/MyDemo/NDKDemo/app/src/main/cpp/crash_test.cpp:?
Stack frame #06 pc 000090ce /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/lib/x86/libmy_native_lib.so (Java_shixin_ndkdemo_MainActivity_testCrash+46): Routine Java_shixin_ndkdemo_MainActivity_testCrash at
//这里输出了错误有关信息行数了
/Users/shixin/Documents/MyProject/MyDemo/NDKDemo/app/src/main/cpp/crash_test.cpp:99
Stack frame #07 pc 000096f8 /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/oat/x86/base.odex (offset 0x9000)
Stack frame #08 pc 00059fff [anon:libc_malloc:afd00000]
Stack frame #09 pc 0150a00f /dev/ashmem/dalvik-main space (region space) (deleted)
Stack frame #10 pc 8bc3b28f <unknown>
Stack frame #11 pc 80c1c541 <unknown>
Stack frame #12 pc 0d3fffff /dev/ashmem/dalvik-main space (region space) (deleted)
- 使用带错误日志的文件:
- 命令:参数-sym 基础上再加个-dump
ndk-stack路径 -sym 工程下abi路径(比如build/intermediates/cmake/debug/obj/armeabi) -dump
日志文件路径
- 使用
./ndk-stack -sym /MyDemo/NDKDemo/app/build/intermediates/cmake/debug/obj/x86 -dump /crash_test.txt
输出:
********** Crash dump: **********
Build fingerprint: 'google/sdk_gphone_x86/generic_x86:8.0.0/OSR1.170901.056/4497355:userdebug/dev-keys'
pid: 11596, tid: 11596, name: shixin.ndkdemo >>> shixin.ndkdemo <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Stack frame #00 pc 00000ac4 [vdso:affad000] (__kernel_vsyscall+16)
Stack frame #01 pc 00075b3c /system/lib/libc.so (tgkill+28)
Stack frame #02 pc 0001f04e /system/lib/libc.so (abort+110)
Stack frame #03 pc 0002720e /system/lib/libc.so (__libc_fatal+46)
Stack frame #04 pc 00072f63 /system/lib/libc.so (__stack_chk_fail+35)
Stack frame #05 pc 00008ec2 /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/lib/x86/libmy_native_lib.so (_Z12arrayPointerv+194): Routine arrayPointer() at /Users/shixin/Documents/MyProject/MyDemo/NDKDemo/app/src/main/cpp/crash_test.cpp:?
Stack frame #06 pc 000090ce /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/lib/x86/libmy_native_lib.so (Java_shixin_ndkdemo_MainActivity_testCrash+46): Routine Java_shixin_ndkdemo_MainActivity_testCrash at /Users/shixin/Documents/MyProject/MyDemo/NDKDemo/app/src/main/cpp/crash_test.cpp:99
Stack frame #07 pc 000096f8 /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/oat/x86/base.odex (offset 0x9000)
Stack frame #08 pc 00059fff [anon:libc_malloc:afd00000]
Stack frame #09 pc 016cf007 /dev/ashmem/dalvik-main space (region space) (deleted)
Stack frame #10 pc 8bc3b28f <unknown>
Stack frame #11 pc 80c1c541 <unknown>
Stack frame #12 pc 0d3fffff /dev/ashmem/dalvik-main space (region space) (deleted)
Crash dump is completed
********** Crash dump: **********
Build fingerprint: 'google/sdk_gphone_x86/generic_x86:8.0.0/OSR1.170901.056/4497355:userdebug/dev-keys'
pid: 11627, tid: 11627, name: shixin.ndkdemo >>> shixin.ndkdemo <<<
signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
Stack frame #00 pc 00000ac4 [vdso:affad000] (__kernel_vsyscall+16)
Stack frame #01 pc 00075b3c /system/lib/libc.so (tgkill+28)
Stack frame #02 pc 0001f04e /system/lib/libc.so (abort+110)
Stack frame #03 pc 0002720e /system/lib/libc.so (__libc_fatal+46)
Stack frame #04 pc 00072f63 /system/lib/libc.so (__stack_chk_fail+35)
Stack frame #05 pc 00008ec2 /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/lib/x86/libmy_native_lib.so (_Z12arrayPointerv+194): Routine arrayPointer() at /Users/shixin/Documents/MyProject/MyDemo/NDKDemo/app/src/main/cpp/crash_test.cpp:?
Stack frame #06 pc 000090ce /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/lib/x86/libmy_native_lib.so (Java_shixin_ndkdemo_MainActivity_testCrash+46): Routine Java_shixin_ndkdemo_MainActivity_testCrash at
//错误信息对应源文件路径
/Users/shixin/Documents/MyProject/MyDemo/NDKDemo/app/src/main/cpp/crash_test.cpp:99
Stack frame #07 pc 000096f8 /data/app/shixin.ndkdemo-DtANX0oY1bKGylfJQXqMVg==/oat/x86/base.odex (offset 0x9000)
Stack frame #08 pc 00059fff [anon:libc_malloc:afd00000]
Stack frame #09 pc 016d1dcf /dev/ashmem/dalvik-main space (region space) (deleted)
Stack frame #10 pc 8bc3b28f <unknown>
Stack frame #11 pc 80c1c541 <unknown>
Stack frame #12 pc 0d3fffff /dev/ashmem/dalvik-main space (region space) (deleted)
看也有错误栈对应源文件路径了。
三. 总结
- add2line通过地址查看源文件错误位置
- ndk-stack命令使用更多,通过logcat日志,或日志方式查看错误信息位置