Andorid Studio NDK開發-LLDB調試

LLDB是一個高效的c/c++的調試器,是與LLVM編譯器一塊兒使用,提供了豐富的流程控制和數據檢測,有效的幫忙咱們調試程序。LLDB也已經取代GDB成爲XCode的默認調試器,Android Studio中也可使用LLDB調試NDK程序,在Android Studio也中能夠LLDB,從SDK Tools中下載LLDB最新版本,配合Android Studiogradle-experimental一塊兒調試NDK項目,會更加的方便。javascript

LLDB安裝

Androis StudioToolbar中能夠找到Android的更新圖標,打開能夠看到Android SDK的升級配置,在SDK Tools中能夠找到LLDB的安裝選項。java

安裝LLDB

究竟如何使用LLDB調試NDK程序呢?在上一篇的Andorid Studio NDK 開發 - NDK 開發利器 gradle-experimental中介紹了使用gradle-experimental能夠簡化NDK的開發配置,其中提到了在運行選項中有兩個運行的配置選項appapp-native,其中的app-native就是用來運行和調試JNI開發的。app-native不單單能夠直接運行,也能夠進行Debug,選中aap-native以後,直接選擇debug按鈕就能夠進入NDK的Debug模式android

Debug JNI

選擇app-native,點擊debug按鈕能夠直接進入Debug狀態,在一段代碼處設置一個斷點,如圖所示:c++

斷點

能夠看到程序運行到斷點出,就進入了Debug狀態,在左側的狀態裏面能夠看到變量的值和指針地址:app

變量信息

程序進入了Debugz狀態,可是並無使用到 LLDB,下面就使用下 LLDB強大的功能。

使用LLDB

從上面的圖中能夠看到除了Variables的Tab頁之外,還有一個Tab頁就是LLDB,點擊進入能夠看到(lldb)的命令行,在命令行裏面能夠輸入LLDB的命令,LLDB命令有不少強大的能力,好比,打印,尋址,調用堆棧等,經過這些命令能夠有效的幫助調試NDK程序。post

lldb

上圖中使用p(print)打印命令打印出了 chars變量的內容,打印的內容包括變量的類型:char[10],變量的值:"i am test"。

LLDB經常使用命令

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

相關文章
相關標籤/搜索