【從0開始搭建app】LLDB調(diào)試

LLDB是個開源的內(nèi)置于XCode的具有REPL(read-eval-print-loop)特征的Debugger,其可以安裝C++或者Python插件。

本系列針對于已經(jīng)知道何為debugger,且有g(shù)db或者lldb使用經(jīng)驗的讀者。對于lldb的嫻熟使用者,也可以用來作為查閱手冊。

這一篇,我們講述lldb內(nèi)建的命令。

lldb與gdb命令名的對照表:http://lldb.llvm.org/lldb-gdb.html

1.help命令

單單執(zhí)行help命令會列出所有命令列表,用戶加載的插件一般來說列在最后。

執(zhí)行help 可以打印指定command的幫助信息,至于插件提供的命令,其幫助信息取決于插件本身的實現(xiàn)。

例如 help print會打印內(nèi)建命令print的使用幫助。

2.print命令

print命令的簡化方式有prin pri p,唯獨pr不能用來作為檢查,因為會和process混淆,幸運的是p被lldb實現(xiàn)為特指print。

實際上你會發(fā)現(xiàn),lldb對于命令的簡稱,是頭部匹配方式,只要不混淆,你可以隨意簡稱某個命令。

例如:

lldb命令print示例

值得說明的是,返回的$0是命令結(jié)果的引用名,使用$0可以進(jìn)行print $0 + 7這樣打印出106,當(dāng)然,$0可以被用于任何其他表達(dá)式或者接收參數(shù)的命令。

3.expression命令

expression命令可以用來修改變量的值,當(dāng)然大部分情況下,使用xcode提供的可視化編輯器更方便。

1

2

3

4

(lldb) p count

(NSUInteger) $4 = 12

(lldb)e count = 42

(NSUInteger) $5 = 42

實際上print相當(dāng)于expression --,而--的意思是命令的參數(shù)終止,跟在--后面的都是命令的輸入數(shù)據(jù)。

要打印一個對象,則需要使用e -O -- anObj,而e -O -- 的縮寫正是我們常用的po命令:

1

2

3

4

5

(lldb) po $8

(

foo,

bar

)

要按特定格式來打印一個變量則使用p/

命令:

1

2

3

4

5

6

7

8

(lldb) p 16

16

(lldb)p/x 16

0x10

(lldb) p/t 16

0b00000000000000000000000000010000

(lldb) p/t (char)16

0b00010000

或者使用p/c打印字符,p/s打印c字符串,詳細(xì)格式查閱這里。

既然我們已經(jīng)知道print實際上是expression --的簡寫,那么在p(或者po)后面跟上復(fù)雜的表達(dá)式則可以先計算表達(dá)式再打印最后的計算結(jié)果。

1

2

3

4

5

6

7

8

9

10

11

(lldb) e int $a = 2

(lldb) p $a * 19

38

(lldb) e NSArray *$array = @[ @"Saturday", @"Sunday", @"Monday" ]

(lldb) p [$array count]

2

(lldb) po [[$array objectAtIndex:0] uppercaseString]

SATURDAY

(lldb) p [[$array objectAtIndex:$a] characterAtIndex:0]

error: no known method '-characterAtIndex:'; cast the message send to the method's return type

error: 1 errors parsing expression

值得注意的是,一旦出現(xiàn)了上述錯誤提示,說明lldb無法判定某一步的計算結(jié)果是什么數(shù)據(jù)類型,這時需要強制類型轉(zhuǎn)換來告訴lldb:

1

2

3

4

(lldb) p (char)[[$array objectAtIndex:$a] characterAtIndex:0]

'M'

(lldb) p/d (char)[[$array objectAtIndex:$a] characterAtIndex:0]

77

4.流程控制命令

實際上使用xcode自帶的可視化工具來控制“繼續(xù)”“暫?!薄跋乱徊健薄斑M(jìn)入”“跳出”更簡單,但這里還是列出其所對應(yīng)的命令名:

繼續(xù):process continue, continue, c

下一步:thread step-over, next, n

進(jìn)入:thread step-in, step, s

跳出:thread step-out, finish, f

5.thread return命令

執(zhí)行thread return命令可以使得當(dāng)前函數(shù)立即返回,也就是說,后續(xù)代碼都不會執(zhí)行了。當(dāng)然執(zhí)行此命令可能會使得arc的計數(shù)追蹤出現(xiàn)錯亂。

thread return命令需要一個參數(shù)來指明函數(shù)強制返回時的返回值。

6.斷點命令

一般來說,在xcode中新建/刪除“行斷點”是很容易的,但是斷點還有很多進(jìn)階使用方法:

條件斷點、條件執(zhí)行、記錄日志、自動繼續(xù)、重復(fù)斷點跳過。

使用xcode提供的可視化工具來操作是很容易的:

lldb斷點命令

7.在debugger中執(zhí)行任意代碼

1

2

3

4

5

6

7

(lldb) e char *$str = (char *)malloc(128)

(lldb) e (void)strcpy($str, "wxrld of warcraft")

(lldb) e $str[1] = 'o'

(char) $0 = 'o'

(lldb) p $str

(char *) $str = 0x00007fd04a900040 "world of warcraft"

(lldb) e (void)free($str)

所以,在debugger中可以修改view的顏色、尺寸、甚至創(chuàng)建controller來push。

8.watchpoint

watchpoint可以在某個變量被寫入/讀取時暫停程序運行:

1

2

3

4

5

6

7

8

9

10

11

(lldb) watchpoint set expression -- (int*)&_abc4

Watchpoint created: Watchpoint 7: addr = 0x15e36d3c size = 4 state = enabled type = w

new value: 0x00000000

(lldb) watchpoint set v -w read _abc4

Watchpoint created: Watchpoint 8: addr = 0x15e36d3c size = 4 state = enabled type = r

watchpoint spec = '_abc4'

new value: 0

(lldb) watchpoint set v -w read_write _abc3

Watchpoint created: Watchpoint 9: addr = 0x15e36d38 size = 4 state = enabled type = rw

watchpoint spec = '_abc3'

new value: 0

實際上可以使用watchpoint來監(jiān)視任意一段內(nèi)存的讀寫。

使用XCode也可以方便地創(chuàng)建watchpoint。

XCode的可視化debug工具中的watch是一個write類型watchpoint(也就是默認(rèn)的)

另外,上述語句中 v是variable的簡寫,同樣的,set可以簡寫為s,watch可以簡寫為wa,而-w后面的參數(shù)是不可以簡寫的必須為read、write或者read_write。

當(dāng)前在arm和x86上,我們一次最多創(chuàng)建4個watchpoint,繼續(xù)創(chuàng)建會提示錯誤。

9.符號斷點

用xcode的可視化工具創(chuàng)建符號斷點很簡單,在Add symbolic breakpoint中填入符號名即可,這里給出objective-c的函數(shù)符號斷點的寫法:

1

2

-[MyViewController viewDidAppear:]

+[MyViewController sharedInstance]

10.查看內(nèi)存

使用XCode的可視化工具來查看memory,要注意watch memory of "p" 和watch memory of "*p"的區(qū)別。

手動執(zhí)行命令可以help x或者 help memory。

小結(jié)

lldb的用法很靈活多樣,但是XCode的可視化調(diào)試工具覆蓋面有限,一些高級用法仍需手動輸入命令,甚至結(jié)合python腳本

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 你是否曾經(jīng)苦惱于理解你的代碼,而去嘗試打印一個變量的值? NSLog(@"%@", whatIsInsideThi...
    木易林1閱讀 1,046評論 0 4
  • 你是否曾經(jīng)苦惱于理解你的代碼,而去嘗試打印一個變量的值? NSLog(@"%@", whatIsInsideThi...
    paraneaeee閱讀 1,339評論 0 7
  • 轉(zhuǎn)載 與調(diào)試器共舞 - LLDB 的華爾茲: https://objccn.io/issue-19-2/ 推薦:i...
    F麥子閱讀 3,463評論 0 10
  • 與調(diào)試器共舞 - LLDB 的華爾茲 nangege 2014/12/19 你是否曾經(jīng)苦惱于理解你的代碼,而去嘗試...
    McDan閱讀 961評論 0 0
  • LLDB的Xcode默認(rèn)的調(diào)試器,它與LLVM編譯器一起,帶給我們更豐富的流程控制和數(shù)據(jù)檢測的調(diào)試功能。平時用Xc...
    CoderSC閱讀 1,516評論 0 2

友情鏈接更多精彩內(nèi)容