LLDB
是一个高效的c/c++
的调试器,是与LLVM编译器
一块儿使用,提供了丰富的流程控制和数据检测,有效的帮忙咱们调试程序。LLDB
也已经取代GDB成为XCode的默认调试器,Android Studio
中也可使用LLDB
调试NDK程序,在Android Studio
也中能够LLDB
,从SDK Tools
中下载LLDB
最新版本,配合Android Studio
和gradle-experimental
一块儿调试NDK项目,会更加的方便。javascript
在Androis Studio
的Toolbar
中能够找到Android的更新图标,打开能够看到Android SDK的升级配置,在SDK Tools
中能够找到LLDB
的安装选项。java
究竟如何使用LLDB
调试NDK程序呢?在上一篇的Andorid Studio NDK 开发 - NDK 开发利器 gradle-experimental中介绍了使用gradle-experimental
能够简化NDK的开发配置,其中提到了在运行选项中有两个运行的配置选项app
和app-native
,其中的app-native就是用来运行和调试JNI开发的。app-native
不单单能够直接运行,也能够进行Debug,选中aap-native
以后,直接选择debug按钮就能够进入NDK的Debug模式android
选择app-native
,点击debug按钮能够直接进入Debug状态,在一段代码处设置一个断点,如图所示:c++
能够看到程序运行到断点出,就进入了Debug状态,在左侧的状态里面能够看到变量的值和指针地址:app
LLDB
,下面就使用下
LLDB
强大的功能。
从上面的图中能够看到除了Variables
的Tab页之外,还有一个Tab页就是LLDB
,点击进入能够看到(lldb)
的命令行,在命令行里面能够输入LLDB
的命令,LLDB
命令有不少强大的能力,好比,打印,寻址,调用堆栈等,经过这些命令能够有效的帮助调试NDK程序。post
chars
变量的内容,打印的内容包括变量的类型:char[10],变量的值:"i am test"。
print (p)打印命令,打印变量以及其值:gradle
p chars
(char [10]) $0 = "i am test"spa
po 仅打印变量的值:命令行
po chars
"i am test"debug
call 就是调用的意思,上述po和p也有调用的功能。通常只在不须要显示输出,或是方法无返回值时使用。例如定义一个变量int p=0,使用call
命令:
call p++
(int) $0 = 1
expr 能够在调试时动态执行指定表达式,并打印结果,用于在调试过程当中修改变量的值
好比咱们在程序里面定义int b=1;能够在断点的时候使用expr
更改其值。
expr b=10
(int) $0 = 10
bt 命令用来堆栈信息,加all可打印全部thread的堆栈,好比咱们增长一段致使崩溃的代码
JNIEXPORT jstring JNICALL
Java_com_jjz_NativeUtil_firstNative(JNIEnv *env, jclass type) {
char chars[] = "i am test";
int p=0;
p=1/0;
return (*env)->NewStringUTF(env, chars);
}复制代码
运行的时候出现了崩溃,这个时候运行bt
命令,获得堆栈信息:
*thread #1, name = 'com.jjz', stop reason = signal SIGFPE
* frame #0: 0xf6ff35e8 libc.so`tgkill + 12
frame #1: 0xf6ff11ec libc.so`pthread_kill + 36
frame #2: 0xf6fcd846 libc.so`raise + 14
frame #3: libexperiment.so`__aeabi_idiv0 at lib1funcs.S:1337
frame #4: libexperiment.so`Java_com_jjz_NativeUtil_firstNative(env=0xf4218ea0, type=0xff8b732c) at experiment.c:16
frame #5: base.odex`java.lang.String com.jjz.NativeUtil.firstNative() at NativeUtil.java:0
frame #6: base.odex`void com.jjz.MainActivity.onCreate(android.os.Bundle) at MainActivity.java:15
frame #7: 0x729d58bf复制代码
image用于寻址,能够用来查找栈地址对应的代码位置,image命令有不少的参数,能够帮助咱们更加清晰的定位问题,其中比较经常使用的是image lookup
:
image lookup --address 0xfxxxxx
0xfxxxxx
表示对应的栈地址,有了地址能够经过image lookup
命令来查看该栈地址上面对应的代码。