天天看點

Xcode 探讨之 LLDB的基本使用

闡述 在LLVM中有一段對LLDB的介紹:

  1. The LLDB project builds on libraries provided by LLVM and Clang to provide a great native debugger. It uses the Clang ASTs and expression parser, LLVM JIT, LLVM disassembler, etc so that it provides an experience that "just works". It is also blazing fast and much more memory efficient than GDB at loading symbols.

從這段話中,我們可以看出LLDV是基于LLVM和Clang庫形成的,它比GDB更快更效率。

在LLDB文章中,也有一段介紹: LLDB is a next generation, high-performance debugger. It is built as a set of reusable components which highly leverage existing libraries in the larger LLVM Project, such as the Clang expression parser and LLVM disassembler. LLDB is the default debugger in Xcode on Mac OS X and supports debugging C, Objective-C and C++ on the desktop and iOS devices and simulator.

LLDB預設就內建中Xcode(4.3+)中,它可以在macOS桌面程式、iOS裝置以及模拟器環境下調試C、Objective-C、C++代碼,但如果你正在使用老一點版本的Xcode的話,那就是GDB調試器。

探讨 基礎前提 LLDB基本文法格式      <command> [<subcommand> [<subcommand>...]] <action> [-options [option-value]] [argument [argument…]]  1.  <command>(指令)和<subcommand>(子指令):LLDB調試指令的名稱。指令和子指令按層級結構來排列:一個指令對象為跟随其的子指令對象建立一個上下文,子指令又為其子指令建立一個上下文,依此類推。  2. <action>:執行指令的操作  3. <options>:指令選項  4. <arguement>:指令的參數  5. []:表示指令是可選的,可以有也可以沒有.

例如 $ breakpoint set -n main  1. command: breakpoint 表示斷點指令 2. action: set 表示設定斷點 3. option: -n 表示根據函數name設定斷點 4. arguement: mian 表示方法名為mian

原始指令(raw指令) LLDB支援不帶指令選項<options>的原始指令(raw指令),原始指令會将指令後面的所有東西當做參數傳遞。不過很多原始指令也可以帶指令選項,當你使用指令選項的時候,需要在指令選項後面添加 ‘--' 區分指令選項和參數。 例如 $ expression -O -- self 

Xcode 探讨之 LLDB的基本使用

'唯一比對' 原則 LLDB的指令遵循唯一比對原則: 假如根據前n個字母已經能唯一比對到某個指令,則隻寫前n個字母等效于寫下完整的指令。舉個例子:

Xcode 探讨之 LLDB的基本使用

基礎指令 expression 指令 expression 指令的作用是執行一個表達式,并将表達式傳回的結果輸出。 expression 完整文法: expression <cmd-options> -- <expr> 1. <cmd-options>: 指令選項,一般情況下使用預設的即可,不需要特别标明。 2. --: 指令選項結束符,表示所有的指令選項已經設定完畢,如果沒有指令選項,--可以省略 ,它其實就是指令選項和表達式之間的分隔符 3. <expr>: 要執行的表達式 說expression是LLDB裡面最重要的指令都不為過。因為他能實作2個功能。

1   執行表達式某個表達式,在運作代碼過程中,可以聽過執行某個表達式來動态改變程式執行的軌迹。     例如我們在運作過程中想把self.view的背景顔色變為紅色,我們可以不必編輯代碼再次Run一下,隻需在合适的地方添加斷點,讓程式進入暫停狀态,用expression修改顔色,再重新整理一界面,就能看到效果。     代碼:     $ expression -- self.view.backgroundColor = [UIColor redColor]       // 改變顔色                 $ expression -- (void)[CATransaction flush]     // 重新整理界面

2   将傳回值輸出,通過expression列印東西      例如我們想列印 self.view      代碼:    $ expression -- self.view

p & print & call 指令 我們很少直接使用expression,畢竟有點長,更多的時候我們使用 p、print、call三個指令。這三個指令其實都是  expression -- 的别名。 1. print:  列印某個東西,可以是變量和表達式 2. p:      可以看做是print的簡寫 3. call:   調用某個方法。 表明上看起來不一樣,實際上都是執行某個表達式,将執行的結果輸出到控制台上。上述名字不同,我猜應該是習慣問題,畢竟開發者都有點懶,不願多想...

在官方文檔中我們可以看見

Xcode 探讨之 LLDB的基本使用

po 指令 Objective-C裡所有的對象都是用指針表示的,是以一般列印的時候,列印出來的是對象的指針,而不是對象本身。如果我們想列印對象,需要使用命名選項 -O, 為了更友善的使用,LLDB為expression -O -- 定義了一個别名 po

Xcode 探讨之 LLDB的基本使用

thread系列指令 thread backtrace & bt 有時候我們想要了解線程堆棧資訊,可以使用thread backtrace 将線程堆棧資訊列印出來 thread backtrace [-c <count>] [-s <frame-index>] [-e <boolean>] -c:設定列印堆棧的幀數(frame) -s:設定從哪個幀(frame)開始列印 -e:是否顯示額外的回溯

bt的效果與thread backtrace效果一直,可以用bt指令來代替thread backtrace。

Xcode 探讨之 LLDB的基本使用

thread return thread return 隻要勇用于調試時我們不希望讓代碼執行某個方法,或者想直接傳回一個想要的值這樣的場景 thread return [<expr>]

Xcode 探讨之 LLDB的基本使用

c & n & s & finish 在調試模式下,我們通常使用滑鼠點選按鈕來控制執行順序,我們現在可以使用 c & n & s & finish 這些指令解放滑鼠了。

Xcode 探讨之 LLDB的基本使用

1. c / continue / thread continue: 這三個指令效果都等同于上圖中第一個按鈕的。表示程式繼續運作 2. n / next / thread step-over: 這三個指令效果等同于上圖第二個按鈕。表示單步運作 3. s / step / thread step-in: 這三個指令效果等同于上圖第三個按鈕。表示進入某個方法 4. finish / step-out: 這兩個指令效果等同于第四個按鈕。表示直接走完目前方法,傳回到上層frame

thread其它指令 1. thread jump: 直接讓程式跳到某一行。由于ARC下編譯器實際插入了不少retain,release指令。跳過一些代碼不執行很可能會造成對象記憶體混亂發生crash。 2. thread list: 列出所有的線程 3. thread select: 選擇某個線程 4. thread until: 傳入一個line的參數,讓程式執行到這行的時候暫停 5. thread info: 輸出目前線程的資訊

frame系列 frame(幀) 代表某一時刻程式執行的狀态,與遊戲與電影幀的概念相似。 通過觀察紅色區域的調用堆棧和右側藍色bt指令顯示的所有frame,我們發現是一一對應的,可以推測: 事件一次調用對應一個frame。

Xcode 探讨之 LLDB的基本使用

frame variable 通過frame variable指令,可以列印出目前frame所有的變量。 如果需要列印指定變量,可以給frame variable傳入參數,如: $ frame variable self->_stirng 注意: frame variable 隻接受變量作為參數,不接收表達式,也就是說我們無法使用getter方法來擷取屬性值,隻能直接使用對應的_成員變量。

frame 其它指令 frame info: 檢視目前frame的資訊 frame select: 選擇某個frame

breakpoint 系列 breakpoint 提供了許多針對斷點的功能強大的子指令。 breakpoint set breakpoint set指令用于設定斷點,配合指令選項<options>可以進行多種方式設定斷點。

使用 -n 指定函數名稱 ( --name <function-name> ) 例如: 我們想給所有類中的viewWillAppear: 設定一個斷點:

Xcode 探讨之 LLDB的基本使用

使用 -f 指定檔案 ( --file <filename> ) 例如: 我們隻需要給ViewController.m檔案中的viewDidLoad設定斷點:

Xcode 探讨之 LLDB的基本使用

注意: 如果函數是寫在對應類cateogory中的,那麼-f 後面的檔案名應該寫 catogory檔案。

使用 -l 指定檔案指定某一行 ( --line <linenum> ) 例如: 我們需要給ViewController.m檔案中第23行設定斷點:

Xcode 探讨之 LLDB的基本使用

注意: 此處的行數是Xcode代碼區左側的行數訓示器辨別的,請不要手動計數。

使用-c 設定條件斷點 ( --condition <expr> ) 例如: convertIntValue:方法接收一個參數,當參數value大于10的時候中斷,設定斷點:

Xcode 探讨之 LLDB的基本使用

使用-o設定單次斷點 ( --one-shot ) 例如:我們需要在convertIntValue:方法隻中斷一次

Xcode 探讨之 LLDB的基本使用

breakpoint command 子系列 當我們需要給斷點添加一些指令,例如每次走到這個斷點的時候,我們都需要列印self對象,那麼隻需要給這個斷點添加po self指令即可。 breakpoint command add 作用就是給斷點添加指令。 例如:  給上方的斷點添加一個指令,可以看出上方的指令Id為2,故

Xcode 探讨之 LLDB的基本使用

-o ( --one-liner)表示增加一條指令。 2表示對id為2的斷點添加指令。 如果讓我們想一次性增加多條指令,可以直接使用add。

Xcode 探讨之 LLDB的基本使用

用DONE來結束代碼書寫,注意DONE的編寫,并且多次對同一個斷點添加指令,後面指令會将前面指令覆寫。

breakpoint command list 用來檢視某個斷點已有的指令

Xcode 探讨之 LLDB的基本使用

breakpoint command delete 用來删除某個斷點已有的指令

Xcode 探讨之 LLDB的基本使用

breakpoint list  用來檢視目前已經設定的斷點清單

Xcode 探讨之 LLDB的基本使用

breakpoint disable/enable 用來失效/啟動某個斷點

Xcode 探讨之 LLDB的基本使用

breakpoint delete 用來删除删除指令的,如果指定指令id,那麼就針對這個指令,如果不加則是删除全部指令

Xcode 探讨之 LLDB的基本使用

watchpoint 系列 watchpoint與breakpoint有點相似,不過breakpoint是針對方法生效的斷點,watchpoint是針對位址生效的斷點。 應用場景: 想知道某個屬性什麼時候被篡改 watchpoint set 用于添加一個watchpoint, 隻要這個位址中的内容變化了,程式就會中斷。 watchpoint set variable 用來觀察變變量或者屬性,傳入的參數是變量名,注意參數不接收方法

Xcode 探讨之 LLDB的基本使用

watchpoint set expression 用來直接觀察傳回方法的位址

Xcode 探讨之 LLDB的基本使用

watchpoint command 子系列 與breakpoint 類似,在watchpoint中也可以添加指令 watchpoint command add 作用就是給斷點添加指令。 例如:  給上方的斷點添加一個指令,可以看出上方的指令Id為3,故

Xcode 探讨之 LLDB的基本使用

-o ( --one-liner)表示增加一條指令。 3表示對id為3的斷點添加指令。 如果讓我們想一次性增加多條指令,可以直接使用add。

Xcode 探讨之 LLDB的基本使用

用DONE來結束代碼書寫,注意DONE的編寫,并且多次對同一個斷點添加指令,後面指令會将前面指令覆寫。

watchpoint command list 用來檢視某個斷點已有的指令

Xcode 探讨之 LLDB的基本使用

watchpoint command delete 用來删除某個斷點已有的指令

Xcode 探讨之 LLDB的基本使用

watchpoint list  用來檢視目前已經設定的斷點清單

Xcode 探讨之 LLDB的基本使用

watchpoint disable/enable 用來失效/啟動某個斷點

Xcode 探讨之 LLDB的基本使用

watchpoint delete 用來删除删除指令的,如果指定指令id,那麼就針對這個指令,如果不加則是删除全部指令

Xcode 探讨之 LLDB的基本使用

help 指令 在LLDB中輸入help可以檢視所有命名的幫助問文檔,如果想查詢具體的指令,可以在後面跟着指令

Xcode 探讨之 LLDB的基本使用

apropos指令 根據指令中的關鍵字,大概搜尋相關指令資訊

Xcode 探讨之 LLDB的基本使用

常用的Debug快捷鍵 功能                                 指令 暫停/繼續                         CMD + Ctrl + Y 斷點失效/生效                   CMD + Y 控制台顯示/隐藏                CMD + Shift + Y 光标切換到控制台              CMD + Shift + C 清空控制台                       CMD + K Step Over                         F6 Step Into                          F7 Step Out                          F8

參考文獻 - http://lldb.llvm.org/index.html  LLDB官方文檔 - http://blog.csdn.net/quanqinyang/article/details/51321338 - http://blog.csdn.net/super_ZJ_iOS/article/details/71859468?locationNum=2&fps=1 - http://blog.csdn.net/u014600626/article/details/77650683