前言
在iOS開發(fā)中經(jīng)常使用NSLog進(jìn)行打印調(diào)試,簡單方便。NSLog每次調(diào)用會(huì)打印大量信息,時(shí)間、名稱、進(jìn)程等信息,多次調(diào)用打印會(huì)消耗資源,程序變慢效率低下,每次調(diào)試完畢要及時(shí)清理NSLog。 另外,每次想要NSLog打印看到信息,需要重新編譯運(yùn)行,對于較大的項(xiàng)目費(fèi)時(shí)費(fèi)力,所以調(diào)試最好使用調(diào)試器,LLDB調(diào)試器功能強(qiáng)大,由于能力有限只能簡單介紹一下LLDB調(diào)試器的皮毛。
LLDB
LLDB是新一代高性能調(diào)試器,是Xcode上的默認(rèn)調(diào)試器,支持調(diào)試C,Objective-C和C ++。LLDB命令結(jié)構(gòu)有統(tǒng)一的格式。
LLDB命令結(jié)構(gòu)
<noun>命令、<verb>命令操作、options命令選項(xiàng)、argument參數(shù)。命令各個(gè)元素之間用空格隔開,如果參數(shù)之中有空格則需要加上雙引號(hào)。如果參數(shù)中帶有反斜杠和雙引號(hào),則需要在其前面加上反斜杠。
options命令選項(xiàng)可以放在命令行的任何地方,但是如果argument參數(shù)以“-”開頭,那么必須在option后面添加“--”結(jié)束標(biāo)志進(jìn)行區(qū)分,從而確定option的正確位置。例如你想啟動(dòng)一程序,“process launch”命令的option為“--stop-at-entry”,同時(shí)希望命令的argument為“-program_arg value”,你應(yīng)該輸入的命令為:
(lldb) process launch --stop-at-entry -- -program_arg value
help,它會(huì)列舉出所有的命令。可以通過 help <command> 來了解更多細(xì)節(jié),例 help print、help thread
詳細(xì)的LLDB命令可以參考 LLDB command examples 命令總覽。
在Xcode中使用LLDB調(diào)試程序
從Xcode 5開始LLDB成為了Xcode的默認(rèn)調(diào)試器。LLDB提供了Xcode的底層調(diào)試環(huán)境,調(diào)試區(qū)域中的控制臺(tái)窗口,用于在Xcode IDE環(huán)境中直接調(diào)用LLDB命令。
print(簡寫 p)打印值。
(lldb) p number (NSInteger) $0 = 1
可以給 print 指定不同的打印格式 print/<fmt>
(lldb) p/x number (NSInteger) $1 = 0x0000000000000001
16進(jìn)制 p/x ,二進(jìn)制(t=two) p/t , 打印字符 p/c , 打印以\0終止的字符串 p/s 。查看所有格式expression(簡寫 e)可改變程序中的值。
(lldb) e string = @“xxx.png”
輸入 help print,可看到 'print' is an abbreviation for 'expression --'. (“print”是 “expression --”的縮寫)po 打印對象
(lldb) po string
可以看到到對象的 description 方法的結(jié)果。和命令 (lldb) e -O -- string一個(gè)效果,e -o -- 的別名就是 po (print object 的縮寫)。image
(lldb) image list
可以查看工程中使用到的庫信息
(lldb) image lookup --address 0x0000000107c3f7d4
查找文件的原始地址
在命令行中使用LLDB調(diào)試程序
Xcode IDE通過將LLDB完全集成到源編輯,構(gòu)建和使用圖形控件的“運(yùn)行調(diào)試”循環(huán),自動(dòng)化了許多這些操作。 從命令行了解這些操作如何工作有助于在Xcode控制臺(tái)窗口中理解和使用LLDB調(diào)試器的功能。
加載程序到LLDB中
首先要?jiǎng)?chuàng)建一個(gè)程序用來調(diào)試。打開終端輸入命令進(jìn)入lldb,載入程序。
$ lldb (lldb) file /Users/Developer/Xcode/Build/Products/Test.app
或者直接載入
$ lldb /Users/Developer/Xcode/Build/Products/Test.app Current executable set to '/Users/Developer/Xcode/Build/Products/Test.appp' (x86_64).
啟動(dòng)程序
(lldb) process launch (lldb) run (lldb) r
可以使用進(jìn)程ID或進(jìn)程名來連接一個(gè)已經(jīng)運(yùn)行的程序,--waitfor選項(xiàng)告訴LLDB等待下一個(gè)名稱為指定名稱的程序出現(xiàn),然后連接它。
(lldb) process attach --pid 123 (lldb) process attach --name Sketch (lldb) process attach --name Sketch --waitfor
breakpoint 設(shè)置斷點(diǎn)
(lldb) breakpoint set --file main.m --line 12 (lldb) breakpoint set -f main.m -l 12
在函數(shù)名為foo處設(shè)置斷點(diǎn):
(lldb) breakpoint set --name foo (lldb) breakpoint set -n foo (lldb) breakpoint set --name foo --name bar
在C++中給所有命名為foo的方法設(shè)置斷點(diǎn)
(lldb) breakpoint set --method foo (lldb) breakpoint set -M foo
在OC中給選擇器名為alignLeftEdges:的設(shè)置斷點(diǎn)
(lldb) breakpoint set --selector alignLeftEdges: (lldb) breakpoint set -S alignLeftEdges:
也可以寫成:
(lldb) breakpoint set -n "-[SKTGraphicView alignLeftEdges:]" (lldb) br s -n "-[SKTGraphicView alignLeftEdges:]"
將斷點(diǎn)限定在一個(gè)特定的可執(zhí)行庫中
(lldb) breakpoint set --shlib foo.dylib --n foo
設(shè)置別名
如果覺得命令行太麻煩可以自定義簡單的名稱,例如:
(lldb) command alias bfl breakpoint set -f %1 -l %2 (lldb) bfl foo.c 12
出去已創(chuàng)建的別名命令
(lldb) command unalias bfl
控制程序
(lldb) thread continue (lldb) thread step-in (lldb) thread step-over (lldb) thread step-out
查看線程狀態(tài)
(lldb) thread list
總結(jié)
LLDB功能強(qiáng)大,可以做的事情很多,這里只是簡單的整理了一下常用的命令,還有許多調(diào)試技巧等待著我們?nèi)グl(fā)現(xiàn),這么強(qiáng)大的調(diào)試器是值得我們花費(fèi)時(shí)間和精力去深入研究的,熟練掌握調(diào)試技能會(huì)極大的提高工作效率。
References
http://lldb.llvm.org/tutorial.html
https://www.objc.io/issues/19-debugging/lldb-debugging/
https://developer.apple.com/library/content/documentation/IDEs/Conceptual/gdb_to_lldb_transition_guide/document/Introduction.html#//apple_ref/doc/uid/TP40012917-CH1-SW1