Android NDK的调试经验

来源:互联网 发布:php csrf token 编辑:程序博客网 时间:2024/05/05 18:34

近期在做智能语音识别的项目,由于涉及到NDK的开发,而之前并没有没有NDK crash log的分析经验,这次积累了一些,分享给大家。

具体的环境搭建想必大家也都知道,详细的配置大家可以问下度娘,这里以我的开发环境来讲下,Eclipse+SDK+NDK(android-ndk-r9d)。

这里把NDK的编译配置也讲一下,以免有人走弯路。
1、打开配置面板。项目右键 -> Properties
这里写图片描述

2、新建编译器。Builders -> New… -> Program

Tab菜单 -> Main ->
Browse File System… 选择ndk目录下ndk-build.cmd文件
Browse Workspace… 选择需要编译的项目
这里写图片描述

Tab菜单 -> Refresh -> 勾选Refresh resources upon completion.
这里写图片描述

Tab菜单 -> Build Options ->
勾选During Auto builds
勾选Specify working set of relevant resources
这里写图片描述

点击Specify Resources… 选择需要编译的项目下的jni目录
这里写图片描述

到此,NDK编译配置就完成了,现在就可以编译你的NDK了。
这里写图片描述

在编译SO成功时,大家有没有注意到在项目根目录下,有个obj目录,这里存放的都是此次编译的中间文件,虽然不会编译进APK里,但调试时会用到。
这里写图片描述

一切都是准备工作,真正分析Crash log才刚刚开始,下边就以我在实际当中遇到的一个log为例。包名和SO名称以及经过处理,可以忽略。

pid: 22258, tid: 2156  >>> com.package <<<signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000014 r0 68ef9718  r1 00000018  r2 00000014  r3 00000000 r4 00000200  r5 6d35b008  r6 00000019  r7 00000003 r8 7587dc78  r9 6ad3bf18  10 7a6fa568  fp 7587dc8c ip 00000000  sp 7587db88  lr 6ad1241d  pc 6ad1248c  cpsr 20000030         #00  pc 0001248c  /data/data/com.package/lib/libXXXSpeechSDK.so         #01  pc 000134ca  /data/data/com.package/lib/libXXXSpeechSDK.so         #02  pc 00010e32  /data/data/com.package/lib/libXXXSpeechSDK.so         #03  pc 00012b5a  /data/data/com.package/lib/libXXXSpeechSDK.so         #04  pc 00012c4e  /data/data/com.package/lib/libXXXSpeechSDK.so         #05  pc 0001370e  /data/data/com.package/lib/libXXXSpeechSDK.so         #06  pc 0001fb70  /system/lib/libdvm.so         #07  pc 0004e8ba  /system/lib/libdvm.so         #08  pc 00029020  /system/lib/libdvm.so         #09  pc 0002d7e8  /system/lib/libdvm.so         #10  pc 0005ff32  /system/lib/libdvm.so         #11  pc 0005ff5a  /system/lib/libdvm.so         #12  pc 0005535a  /system/lib/libdvm.so         #13  pc 00012ff0  /system/lib/libc.so         #14  pc 00012748  /system/lib/libc.so         >>> [translate by crash parser] <<<         #00  pc 0001248c  /data/data/com.package/lib/libXXXSpeechSDK.so         #01  pc 000134ca  /data/data/com.package/lib/libXXXSpeechSDK.so         #02  pc 00010e32  /data/data/com.package/lib/libXXXSpeechSDK.so         #03  pc 00012b5a  /data/data/com.package/lib/libXXXSpeechSDK.so         #04  pc 00012c4e  /data/data/com.package/lib/libXXXSpeechSDK.so         #05  pc 0001370e  /data/data/com.package/lib/libXXXSpeechSDK.so         #06  pc 0001fb70  /system/lib/libdvm.so         #07  pc 0004e8ba  /system/lib/libdvm.so         #08  pc 00029020  /system/lib/libdvm.so         #09  pc 0002d7e8  /system/lib/libdvm.so         #10  pc 0005ff32  /system/lib/libdvm.so         #11  pc 0005ff5a  /system/lib/libdvm.so         #12  pc 0005535a  /system/lib/libdvm.so         #13  pc 00012ff0  /system/lib/libc.so         #14  pc 00012748  /system/lib/libc.so         >>> [Dalvik stack info] <<<code around pc:6ad1246c: 310150c2 3304692c 42a16ae8 f7ffddf8  .P.1,i.3.j.B....6ad1247c: 696ffd59 e04f00f9 99026aeb 3a04185a  Y.oi..O..j..Z..:6ad1248c: 9a026811 589c1c08 2b006b2b f00cd00b  .h.....X+k.+....6ad1249c: 1c21eb4e 1c201c06 eb48f00c 1c301c01  N.!... ...H...0.6ad124ac: ea22f00c f00ce010 1c21eb42 1c201c06  ..".....B.!... .code around lr:6ad123fc: eecef00b 1c049e08 68b01c0d eec8f00b  ...........h....6ad1240c: 1c0b1c02 1c291c20 ed46f00b ea16f00c  .... .)...F.....6ad1241c: b0252300 60b36070 46c0bdf0 00000000  .#%.p`.`...F....6ad1242c: 3fe00000 b087b5f0 31049104 91011c15  ...?.......1....6ad1243c: 23011c0a e0012100 3301c202 42a368ac  ...#.!.....3.h.Bstack:7587db48:  f7a3667e 3f992155 60000000 c07249a2 7587db58:  68ef9b2c 00000800 00000080 00000000 7587db68:  00000080 000001ff 00000190 00000200 7587db78:  6d35b008 00000019 e3a070ad ef9000ad 7587db88:  65e677ed 691b8444 00000018 6ad11f2b   #sp7587db98:  691b8440 68d64898 00000190 6d35b008 7587dba8:  68d64898 00000019 740efb60 6ad134cf 7587dbb8:  00000001 691b8440 00000000 00000003 7587dbc8:  00000190 0000001a 00000016 721c9e78 7587dbd8:  00000001 7217f720 0000000e 686cf3c8 7587dbe8:  00003e80 6ad10e37 686cf3c8 77ab0308 7587dbf8:  6ad10e1f 68ce5d90 7587dc5c 6ad12b5d 7587dc08:  0000000e 68ce5d90 7587dc58 6ad12c53 7587dc18:  7587dc34 436e0550 00003e80 00003e7f 7587dc28:  77aae008 0000f9fc 6ad2a820 6ad12ba1 7587dc38:  6ad22e0d 00000000 00003e80 6ad13711 7587dc48:  7587dc58 00000000 41317578 436d8850 7587dc58:  00000000 00000000 436d8840 62cf59d0 7587dc68:  7a6fa558 00000004 6ad3bf20 41288b74 7587dc78:  6ad3bf14 00000001 42a2fd68 6aee02d1 7587dc88:  00000000 412b78bd 6ad3bf14 6aee02ce 7587dc98:  6ad136a9 7a6fa568 00000000 00000000 7587dca8:  00000001 401dca6c 42dc8c00 42dc8c00 7587dcb8:  00000001 42128018 43585e88 43585e88 7587dcc8:  7a6fa8c4 43585e88 00000003 7a6fa558 7587dcd8:  0000004c 43585e88 00000000 412be98d 7587dce8:  7587dd54 626cc9dc 00000001 4160c6c0 7587dcf8:  00000001 42128018 439d7af0 439d7af0 7587dd08:  42128018 00010fce 00000001 4022766b 7587dd18:  4008f008 413192c0 439d7af0 412d75b5 7587dd28:  413178e8 41317578 00010fce 00000000 7587dd38:  41317578 41295338 7587dd54 f79ebef4 7587dd48:  7587dd54 415a87d8 00010fbe 00000000 7587dd58:  401dca6c 412d0625 42a5d97c 6ad3beec 7587dd68:  1dcd64ff 412bc109 7a6fa558 f79ebef4 7587dd78:  00000001 6aede5b8 6ad3bf34 7a6fa558 7587dd88:  42d09e40 41288d00 00000000 6ad3bf00 7587dd98:  00000000 41292024 00000000 7a6fa558 7587dda8:  41311c5c 627d2628 00000000 7587ddd4 7587ddb8:  7587deb0 00000000 00000000 412967ec 7587ddc8:  00000000 00000000 00000000 00000000 7587ddd8:  6ad3bfe4 00000000 00000000 00000000 7587dde8:  00000000 00000000 00000000 00000000 7587ddf8:  00000000 00000000 00000000 44340000 7587de08:  44a00000 42400000 00000000 00000000 7587de18:  42400000 42400000 3f7ff797 3f000000 7587de28:  3f7ff797 e5caa992 fbfbfbfb fbfbfbfb 7587de38:  7a6fa558 627d2628 7587dea8 427c4008 7587de48:  6ad3bfec 642a5a18 7587deb0 412c8f35 7587de58:  7a6fa558 627d2628 427c4008 7587deb0 7587de68:  412f9b22 401dca6c 627d2628 41317874 7587de78:  00100000 7a6fa558 00000001 412c8f5f 7587de88:  7587deb0 7587dea8 7a6fa558 7587dea8 7587de98:  401dca6c 7a6fa558 412be35f 7587deb0 7587dea8:  71e89d98 00000000 00000000 00000000 7587deb8:  00000000 71e89db0 00000000 00000000 7587dec8:  00000000 71e89dad 71e89d98 f79ebef4 7587ded8:  7587df00 412be289 7a6fa558 00000078 7587dee8:  412be289 4019eff4 6efd71d0 7587df00 7587def8:  bef75738 4019e74c 7587df00 6efd71d0 7587df08:  00000016 00000000 00000000 00000000 7587df18:  7a6fa558 00000000 00000000 00000000 7587df28:  00000000 6b93e260 687f6e20 00000000 7587df38:  00000000 00000000 00000000 00000000 7587df48:  00000000 00000000 00000000 00000000 7587df58:  00000000 00000000 00000000 00000000 7587df68:  00000000 00000000 00000000 00000000 7587df78:  00000000 00000000 00000000 00000000 7587df88:  00000000 00000000 00000000 00000000 7587df98:  00000000 00000000 00000000 00000000 7587dfa8:  00000000 00000000 00000000 00000000 7587dfb8:  00000000 00000000 00000000 00000000 7587dfc8:  00000000 00000000 00000000 00000000 7587dfd8:  00000000 00000000 00000000 00000000 7587dfe8:  00000000 00000000 00000000 00000000 print call stack finish!

获取log的方式不用计较,这是我们对系统log进行过特殊处理获取的。

开发中获取log可以使用

adb logcat -c && adb logcat  > D://crash.log

如果想加过滤可以过滤器
Linux adb logcat -c && adb logcat | find "过滤词" > D://crash.log
Windows adb logcat -c && adb logcat | grep "过滤词" > D://crash.log

libdvm.so是Java层的堆栈关系,可以不用管,本文只分析此次NDK开发的log。

在上述log里,真实的Crash是在这里signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000014
寄存器的位置是00000014,这是个野指针,在log里有指明内存栈的调用,“sp 7587db88”是指从寄存器7587db88开始的,在之后的log里也有输出“7587db88: 65e677ed 691b8444 00000018 6ad11f2b #sp”

我们通过ndk-stack可以把这段log转化成NDK的调用堆栈,注意这里使用的是中间文件下的armeabi目录

D:\WorkStation\install\adt-bundle-windows-x86_64-20140702\android-ndk-r9d>ndk-stack -sym E:\WorkPlace\项\obj\local\armeabi -dump 转换前日志文件 > 转换后的日志文件

这时候的日志就输出成堆栈的调用情况

********** Crash dump: **********Build fingerprint: 'Xiaomi/aries/aries:4.1.1/JRO03L/JLB52.0:user/release-keys'pid: 22258, tid: 2156  >>> com.package <<<signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000014Stack frame          #00  pc 0001248c  /data/data/com.package/lib/libxxxSpeechSDK.so: Routine Realft(float*) at E:\WorkPlace\xxxSpeech\xxxVoiceRecognition/jni/vad/signal_process.cpp:452Stack frame          #01  pc 000134ca  /data/data/com.package/lib/libxxxSpeechSDK.so: Routine qn_sigmoid_vf_vf at E:\WorkPlace\xxxSpeech\xxxVoiceRecognition/jni/vad/QN_fltvec.h:179Stack frame          #02  pc 00010e32  /data/data/com.package/lib/libxxxSpeechSDK.so: Routine ~CMVNFeatureTranslator at E:\WorkPlace\xxxSpeech\xxxVoiceRecognition/jni/vad/feature_translate.cpp:243Stack frame          #03  pc 00012b5a  /data/data/com.package/lib/libxxxSpeechSDK.so: Routine Vader::Init(char*, char*, char*) at E:\WorkPlace\xxxSpeech\xxxVoiceRecognition/jni/vad/vad.cpp:37Stack frame          #04  pc 00012c4e  /data/data/com.package/lib/libxxxSpeechSDK.so: Routine ~Vader at E:\WorkPlace\xxxSpeech\xxxVoiceRecognition/jni/vad/vad.cpp:84Stack frame          #05  pc 0001370e  /data/data/com.package/lib/libxxxSpeechSDK.so: Routine KillFE(FeOption*) at E:\WorkPlace\xxxSpeech\xxxVoiceRecognition/jni/vad/wav2feat.cpp:115Stack frame          #06  pc 0001fb70  /system/lib/libdvm.soStack frame          #07  pc 0004e8ba  /system/lib/libdvm.soStack frame          #08  pc 00029020  /system/lib/libdvm.soStack frame          #09  pc 0002d7e8  /system/lib/libdvm.soStack frame          #10  pc 0005ff32  /system/lib/libdvm.soStack frame          #11  pc 0005ff5a  /system/lib/libdvm.soStack frame          #12  pc 0005535a  /system/lib/libdvm.soStack frame          #13  pc 00012ff0  /system/lib/libc.soStack frame          #14  pc 00012748  /system/lib/libc.so

这个时候就可以根据堆栈分析问题原因了,如果还不够详细,还可以使用arm-linux-androideabi-objdump反编译分析具体哪个指针有问题。

D:\WorkStation\install\adt-bundle-windows-x86_64-20140702\android-ndk-r9d\toolchains\arm-linux-androideabi-4.8\prebuilt\windows-x86_64\bin>arm-linux-androideabi-objdump.exe   -DSl E:\WorkPlace\xxxSpeech\xxxVoiceRecognition\obj\local\armeabi\libxxxSpeechSDK.so > D://core.txt

就可以查看各个文件里每个方法的指针位置,再根据寄存器位置,找到具体有问题的指针。

E:\WorkPlace\xxxSpeech\xxxVoiceRecognition/jni/vad/signal_process.cpp:442        s[i1] = xr1 + wrs * xr2 - wis * xi2;   12330:   00000014    andeq   r0, r0, r4, lsl r0   12334:   14510001    ldrbne  r0, [r1], #-1   12338:   30000000    andcc   r0, r0, r0   1233c:   01000000    mrseq   r0, (UNDEF: 0)   12340:   00305000    eorseq  r5, r0, r0   12344:   01140000    tsteq   r4, r0   12348:   00020000    andeq   r0, r2, r0   1234c:   00006091    muleq   r0, r1, r0   12350:   00000000    andeq   r0, r0, r0   12354:   00020000    andeq   r0, r2, r0   12358:   00180000    andseq  r0, r8, r0   1235c:   00010000    andeq   r0, r1, r0   12360:   00001852    andeq   r1, r0, r2, asr r8   12364:   00009c00    andeq   r9, r0, r0, lsl #24
0 0