1. 手动跟进crash
首先我们先手动写一个错误,在里面写入如下代码:
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
......
int * p = NULL;
*p = 100;
return JNI_VERSION_1_6;
}
运行程序,发现崩溃了,然后查看LogCat:
A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 19118 (.hgy413.ndkdemo)
com.hgy413.ndkdemo
是崩溃的APK的包名。
完全看不懂上面的信息,我们需要用到是ndk-stack
工具,它在我们的ndk根目录下,它可以帮助我们把上面的信息转化为更为易懂更详细的报错信息,下面看看怎么做:
- 切换到
AndroidStudio
中的命令行,输入adb logcat > log.txt
,然后我们就可以在项目根目录下看到NDKDemo\log.txt
文件,打开
搜索上面的fault addr 0x0 in tid 19118
,即可得到以下内容:
--------- beginning of crash
04-16 20:06:09.874 19118 19118 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 19118 (.hgy413.ndkdemo)
..................................// todo 这部分删除
04-16 20:06:10.140 19137 19137 F DEBUG : backtrace:
04-16 20:06:10.141 19137 19137 F DEBUG : #00 pc 0000000000016a44 /data/app/com.hgy413.ndkdemo-1/lib/arm64/libva++.so (JNI_OnLoad+116)
04-16 20:06:10.141 19137 19137 F DEBUG : #01 pc 00000000002f2c34 /system/lib64/libart.so (_ZN3art9JavaVMExt17LoadNativeLibraryEP7_JNIEnvRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEP8_jobjectP8_jstringPS9_+2136)
04-16 20:06:10.141 19137 19137 F DEBUG : #02 pc 000000000000427c /system/lib64/libopenjdkjvm.so (JVM_NativeLoad+280)
04-16 20:06:10.141 19137 19137 F DEBUG : #03 pc 00000000005de630 /system/framework/arm64/boot.oat (offset 0x54e000) (java.lang.Runtime.nativeLoad+204)
04-16 20:06:10.141 19137 19137 F DEBUG : #04 pc 00000000005de0d0 /system/framework/arm64/boot.oat (offset 0x54e000) (java.lang.Runtime.doLoad+204)
04-16 20:06:10.141 19137 19137 F DEBUG : #05 pc 00000000005dff00 /system/framework/arm64/boot.oat (offset 0x54e000) (java.lang.Runtime.loadLibrary0+748)
04-16 20:06:10.141 19137 19137 F DEBUG : #06 pc 0000000000601e24 /system/framework/arm64/boot.oat (offset 0x54e000) (java.lang.System.loadLibrary+96)
这里可以基本看到是崩在JNI_OnLoad+116
处。
- 继续在
AndroidStudio
中的命令行中输入如下命令(在这之前,我们要将ndk-stack
的路径添加到环境变量,以便于我们在命令行中直接使用它,当然,你也可以写全路径):
......>C:\Users\Administrator\AppData\Local\Android\Sdk\ndk-bundle\ndk-stack -sym lib\build\intermediates\ndkBuild\debug\obj\local\arm64-v8a -dump ./log.txt
********** Crash dump: **********
Build fingerprint: 'Xiaomi/santoni/santoni:7.1.2/N2G47H/9.4.11:user/release-keys'
#00 0x0000000000016a44 /data/app/com.hgy413.ndkdemo-1/lib/arm64/libva++.so (JNI_OnLoad+116)
JNI_OnLoad
C:/H/project/AndroidX/luluboxtest/NDKDemo/lib/src/main/myjni\Environment.cpp:21:8
#01 0x00000000002f2c34 /system/lib64/libart.so (_ZN3art9JavaVMExt17LoadNativeLibraryEP7_JNIEnvRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEP8_jobjectP8_jstringPS9_+2136)
#02 0x000000000000427c /system/lib64/libopenjdkjvm.so (JVM_NativeLoad+280)
#03 0x00000000005de630 /system/framework/arm64/boot.oat (offset 0x54e000) (java.lang.Runtime.nativeLoad+204)
-dump
参数很容易理解, 即dump下来的log
文本文件. ndk-stack
会分析此文件,即前面adb logcat > log.txt
生成的log.txt
文件。
-sym
参数就是你android项目下,编译成功之后,obj
目录下的文件,如lib\build\intermediates\ndkBuild\debug\obj\local\arm64-v8a
,找不到就直接在本项目下搜obj
关键字。
libs目录下生成的库是剥离了符号表与调试信息的,而
obj
下的库是带有调试信息的。
- 上面的两步可以合成一步:
.......>adb logcat | C:\Users\Administrator\AppData\Local\Android\Sdk\ndk-bundle\ndk-stack -sym lib\build\intermediates\ndkBuild\debug\obj\local\arm64-v8a
********** Crash dump: **********
Build fingerprint: 'Xiaomi/santoni/santoni:7.1.2/N2G47H/9.4.11:user/release-keys'
#00 0x0000000000016a44 /data/app/com.hgy413.ndkdemo-1/lib/arm64/libva++.so (JNI_OnLoad+116)
JNI_OnLoad
C:/H/project/AndroidX/luluboxtest/NDKDemo/lib/src/main/myjni\Environment.cpp:21:8
......
myjni\Environment.cpp:21:8
准确的指出了发生错误的行数:
2.google Breakpad
3.LL ndk debug调试
lib工程的build.gradle增加:
buildTypes {
debug {
jniDebuggable true //此句不加在真机上 debug 不受影响,但是在虚拟机上不能 debug
}
release {
consumerProguardFiles 'proguard-rules.pro'
//proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
mk添加:
APP_OPTIM := debug
adb logcat | C:\Users\hgy413\AppData\Local\Android\Sdk\ndk-bundle\ndk-stack -sym lib\build\intermediates\ndkBuild\debug\obj\local\armeabi-v7a
4.
SET(CMAKE_BUILD_TYPE “Debug”)
adb logcat | C:\Users\hgy413\AppData\Local\Android\Sdk\ndk\21.3.6528147\ndk-stack -sym engine\build\intermediates\cmake\debug\obj\armeabi-v7a