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
命令來查看該棧地址上面對應的代碼。