常见错误:
初始化错误 数组/迭代器/指针访问越界 访问无效/空指针对象 内存泄露 参数错误 堆栈溢出 类型转换错误 等
1,日志及其解释:
日志收集,默认已经有了哈,如果是自己测试收集日志可以直接:adb logcat -b crash > logs.txt
06-30 18:19:07.867 F/DEBUG (32224): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
06-30 18:19:07.868 F/DEBUG (32224): Build fingerprint: 'Redmi/phoenix/phoenix:10/QKQ1.190825.002/V11.0.13.0.QGHCNXM:user/release-keys'
06-30 18:19:07.868 F/DEBUG (32224): Revision: '0'
06-30 18:19:07.868 F/DEBUG (32224): ABI: 'arm'
06-30 18:19:07.868 F/DEBUG (32224): Timestamp: 2021-06-30 18:19:07+0800
06-30 18:19:07.868 F/DEBUG (32224): pid: 32190, tid: 32214, name: Thread-3 >>> com.eastmoney.avdemo <<<
06-30 18:19:07.868 F/DEBUG (32224): uid: 10432
06-30 18:19:07.868 F/DEBUG (32224): signal 4 (SIGILL), code 1 (ILL_ILLOPC), fault addr 0xc275e21c (*pc=0x03eeca)
06-30 18:19:07.868 F/DEBUG (32224): r0 00000000 r1 adc5b26a r2 00430000 r3 00000003
06-30 18:19:07.868 F/DEBUG (32224): r4 c275dfc5 r5 d3ced500 r6 bfb83000 r7 c207b938
06-30 18:19:07.868 F/DEBUG (32224): r8 00000000 r9 d2df1200 r10 c207ba68 r11 c207b9ec
06-30 18:19:07.868 F/DEBUG (32224): ip eb3f7464 sp c207b920 lr eb38a51f pc c275e21c
06-30 18:19:07.893 I/chatty ( 891): uid=1000(system) Binder:891_1 identical 2 lines
06-30 18:19:07.913 D/BufferQueueLayer( 891): Launcher new frame Arrived
06-30 18:19:07.919 W/AudioFlinger( 886): RecordThread: buffer overflow
06-30 18:19:07.927 D/BufferQueueLayer( 891): Launcher new frame Arrived
06-30 18:19:08.057 F/DEBUG (32224):
06-30 18:19:08.057 F/DEBUG (32224): backtrace:
06-30 18:19:08.057 F/DEBUG (32224):
06-30 18:19:08.057 F/DEBUG (32224):
06-30 18:19:08.057 F/DEBUG (32224):
...
其中的日志含义大概解释如下(按照行解释): 第二行是当前rom的fingerprint,一般包含了手机的牌子(redmi)、android系统版本(10)、MIUI版本(V11.0.13.0.QGHCNXM)、release版本(rom一般内部测试版是debug版); 第四行是当前的cpu架构:arm; 第五行是crash的时间戳:2021-06-30 18:19:07+0800; 第六行是当前的进程Id、线程Id\名字和applicationId(一般主线程crash的话这里的进程Id和线程Id一样); 后面的是 错误地址:fault addr 0xc275e21c (*pc=0x03eeca); 寄存器的dump信息:rx/dx等(r0 00000000 r1 adc5b26a r2 00430000 r3 00000003); 崩溃的地方调用堆栈信息: #00 pc 0000b21c /data/app/com … 。
上面日志可以看到自己的so库是libmp3lame.so,
2,使用工具定位问题代码
2.1,ndk-stack
上面日志里面的backtrace已经显示了代码的调用堆栈了,如果没有显示,可以使用ndk自带的ndk-stack工具转换成带调用栈信息的日志,命令格式和使用如下:
格式:
Usage: ndk-stack -sym PATH [-dump PATH]
Symbolizes the stack trace from an Android native crash.
-sym PATH sets the root directory for symbols
-dump PATH sets the file containing the crash dump (default stdin)
See <https://developer.android.com/ndk/guides/ndk-stack.html>.
使用
D:\>ndk-stack -sym D:\Work\WorkSpace\AVDemo\app\build\intermediates\ndkBuild\release\obj\local\armeabi\libmp3lame.so -dump D:\logs.txt
得到下面:
注意,上面的so库是要带symbols的,比打包进apk的要大很多,项目中位置是:app\build\intermediates\ndkBuild\debug\obj\local\armeabi\libmp3lame.so。 还有,上面的行号不是源码中的行号,但是通过上下行也可以看到调用顺序。
2.2,addr2line.exe
要想知道具体的源码调用行号,需要使用arm-linux-androideabi-addr2line.exe,
使用格式: arm-linux-androideabi-addr2line –e XXXX.so pc地址1 pc地址2 … 如下:
D:\Program_Files\NDK\android-ndk-r13b-windows-x86_64\android-ndk-r13b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin>arm-linux-androideabi-addr2line.exe -e D:\Work\WorkSpace\AVDemo\app\build\intermediates\ndkBuild\release\obj\local\armeabi\libmp3lame.so 0000b21c
D:/Work/WorkSpace/AVDemo/app/src/main/cpp/lame/./native-lib.cpp:26
2.3,objdump.exe
如果还想看看so转汇编的文件可以使用objdump工具,这个可以再次确认具体的错误地址对应的是哪个方法。 命令如下:
D:\>D:\Program_Files\NDK\android-ndk-r13b-windows-x86_64\android-ndk-r13b\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\bin\arm-linux-androideabi-objdump.exe -S D:\Work\WorkSpace\AVDemo\app\build\intermediates\ndkBuild\release\obj\local\armeabi\libmp3lame.so > lxs.asm
得到的lxs.asm文件如下:
extern "C"
JNIEXPORT jint JNICALL
Java_com_eastmoney_avdemo_MainActivity_encode(JNIEnv *env, jobject thiz, jbyteArray buffer_l,
jbyteArray buffer_r, jint length) {
b1b0: b5f0 push {r4, r5, r6, r7, lr}
b1b2: af03 add r7, sp,
b1b4: b083 sub sp,
b1b6: b404 push {r2}
b1b8: bc40 pop {r6}
b1ba: 9601 str r6, [sp,
b1bc: b401 push {r0}
b1be: bc20 pop {r5}
...
b20a: b420 push {r5}
b20c: bc01 pop {r0}
b20e: 9901 ldr r1, [sp,
b210: b440 push {r6}
b212: bc04 pop {r2}
b214: 9b02 ldr r3, [sp,
b216: f031 fd23 bl 3cc60 <__aeabi_llsl+0x16c>
b21a: 46c0 nop ; (mov r8, r8)
b21c: 0003eeca .word 0x0003eeca
上图的最后一行可以看到,和错误地址:fault addr 0xc275e21c (*pc=0x03eeca)对应上了,也和PC地址pc 0000b21c 对应上了。 可以查看到确认是代码中最后一行没有renturn导致crash。
|