前言
我们在项目开发过程中可能会因为考虑不周或者对象,变量,方法使用不当导致程序产生bug,严重的时候会导致程序崩溃无法用。在平常开发中,当我们的Android程序crash的时候,我们可以通过Android studio logcat等工具快速定位等crach产生位置
如下图:
是因为textview空指针问题导致等。
但是在 NDK 项目开发中,在 C/C SDK 出现 crash 的的时候。如下图:通过搜索 logcat 抓到的日志,只能定位到图中 哪个pid 进程 ID ,tid 线程 ID 出现了问题,开发者无法直观的排查错误原因
使用ndk-stack输出调用堆栈
linux 系统中进程 crash 后通过 backtrace 输出堆栈信息,开发者是基于这些堆栈信息来定位代码问题。我们可以使用ndk-stack
打印对应的崩溃日志
使用方法
要使用 ndk-stack,您首先要有一个包含未剥离版应用共享库的目录。如果您使用 ndk-build,则可在 $PROJECT_PATH/obj/local/<abi> 中找到这些未剥离版共享库,其中 <abi> 是您设备的 ABI。
使用此工具的方式有两种。您可以将 logcat 文本作为直接输入馈送到程序。例如
代码语言:txt复制adb logcat | $NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi-v7a
您也可以使用 -dump 选项将 logcat 指定为输入文件。例如:
代码语言:txt复制adb logcat > /tmp/foo.txt
$NDK/ndk-stack -sym $PROJECT_PATH/obj/local/armeabi-v7a -dump foo.txt
该工具会在开始解析 logcat 输出时查找第一行星号。例如
代码语言:txt复制*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
使用示范
1.现在cpp文件中添加native方法,用于产生一个crash
代码语言:txt复制extern "C"
JNIEXPORT void JNICALL
Java_com_pengjie0668_demo_MainActivity_makeCrash(JNIEnv *env, jobject instance, jstring input_)
{
const char *input = env->GetStringUTFChars(input_, 0);
strcpy("output", input);
}
2.然后在java层调用传入空值:
3.最后在Terminal中入命令
代码语言:txt复制 adb logcat | /Users/pj1053/Library/Android/sdk/ndk-bundle/ndk-stack -sym /Users/pj1053/Downloads/NDKDemo/app/build/intermediates/cmake/debug/obj/arm64-v8a
如图
在Android Studio编译运行,点击文本按键,观察控制台,如下图
可以看出cpp 文件出错的行数,对应的函数名是Java_com_pengjie0668_demo_MainActivity_makeCrash
内的strcpy方法。
GitHub Demo下载链接