Xcode lldb 調(diào)試器

lldb 是 Xcode 中集成的一個(gè)開(kāi)源調(diào)試器,可以減少我們每次調(diào)試程序時(shí)需要重新啟動(dòng)程序并逐級(jí)進(jìn)入到指定頁(yè)面的時(shí)間舌稀。
要使用 lldb 除了在代碼中加斷點(diǎn)外列肢,還可以在程序運(yùn)行時(shí)點(diǎn)擊控制臺(tái)上方第三個(gè)指令(Pause program execution)使程序進(jìn)入暫停狀態(tài)陕截。
查看 lldb 的具體命令,可以通過(guò)在控制臺(tái)輸入 help 后回車查看挣惰。


下面介紹一些常用的命令

print

Evaluate an expression on the current thread. Displays any returned value with LLDB's default formatting.
計(jì)算當(dāng)前線程上的表達(dá)式。使用LLDB的默認(rèn)格式顯示任何返回值殴边。
簡(jiǎn)寫(xiě):p憎茂,使用如圖

lldb_p.png

可以看到 p 命令能打印出變量的值及其類型,其中0表示這是 lldb 調(diào)試器當(dāng)前調(diào)試的第0個(gè)锤岸,同樣的1 表示第1個(gè)竖幔,以此類推,后續(xù)可以用 $+數(shù)字表示該結(jié)果是偷,以執(zhí)行其他命令拳氢。

expression

Evaluate an expression on the current thread. Displays any returned value with LLDB's default formatting.
計(jì)算當(dāng)前線程上的表達(dá)式募逞。使用LLDB的默認(rèn)格式顯示任何返回值。
如果要改變一個(gè)值馋评,可使用 expression 命令放接,簡(jiǎn)寫(xiě) p,使用如下圖

lldb_e.png

e 不僅可以改變控制器中的值栗恩,還可以改變程序中的值透乾。
注意 pe 不帶參數(shù)的簡(jiǎn)寫(xiě)。
當(dāng)使用 p 打印對(duì)象時(shí)磕秤,只會(huì)打印出指針地址乳乌,這時(shí)我們可以使用 poe 的另一種格式)來(lái)實(shí)現(xiàn)。
p 命令還可以設(shè)置打印格式市咆,打印格式語(yǔ)法 pring/<fmt> 或 p/<fmt>
默認(rèn)格式

// 十進(jìn)制
(lldb) p 16
16
// 十六進(jìn)制
(lldb) p/x 16
0x10
// 二進(jìn)制(t 代表 two)
(lldb) po/t 16
0b00000000000000000000000000010000
(lldb) po/t (char)16
0b00010000

lldb 定義變量

使用 lldb 定義變量需要在變量前以 $ 開(kāi)頭汉操,如下

(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

注意最后一個(gè)報(bào)錯(cuò)了,因?yàn)闆](méi)有明確返回類型蒙兰,解決如下

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

流程控制相關(guān)

在調(diào)試程序的時(shí)候控制臺(tái)上方工具欄一部分如下圖

lldb_工具條.png

從左只有磷瘤,3-7分別為 continue \ step over \ step into \ step out
contine(c):取消程序的暫停,允許程序正常執(zhí)行下去直到遇到下一個(gè)斷點(diǎn)搜变。
step over(next 或 n):黑盒方式執(zhí)行下一行代碼采缚,如果所在行是一個(gè)方法調(diào)用,不會(huì)跳進(jìn)這個(gè)方法挠他,而是執(zhí)行這個(gè)方法扳抽,然后繼續(xù)。
step into(step 或 s):跳進(jìn)一個(gè)方法調(diào)試殖侵,若當(dāng)前行不是方法調(diào)用贸呢,作用和 n 相同。
step out:如果不小心跳進(jìn)一個(gè)方法拢军,使用 step out 命令可以繼續(xù)執(zhí)行到下一個(gè)返回語(yǔ)句然后再次停止楞陷。

Thread Return

調(diào)試時(shí),使用 thread return 可以控制程序流程茉唉。
thread return 有一個(gè)可選參數(shù)固蛾,在執(zhí)行時(shí)它會(huì)把可選參數(shù)加載進(jìn)返回寄存器里,然后立刻執(zhí)行返回命令赌渣,跳出當(dāng)前棧幀魏铅。這意味著方法剩余的部分不會(huì)被執(zhí)行。(提前跳出方法)
這會(huì)給 ARC 的引用計(jì)數(shù)造成一些問(wèn)題坚芜,或者會(huì)使方法內(nèi)的清理部分失效览芳。但是在方法的開(kāi)頭執(zhí)行這個(gè)命令,是個(gè)非常好的隔離這個(gè)方法鸿竖,偽造返回值的方式 沧竟。

管理斷點(diǎn)

Xcode 左側(cè) Navigator 倒數(shù)第二個(gè)選項(xiàng)(看起來(lái)像一個(gè)斷點(diǎn))下铸敏,這是衣蛾可以快速管理所有斷點(diǎn)的面板。
lldb 同樣可以做這件事悟泵,breakpoint listbr li)命令可以查看當(dāng)前項(xiàng)目下所有的斷點(diǎn)及其位置杈笔。
breakpoint enable <breakpointID>breakpoint disable <breakpointID>命令可以用來(lái)開(kāi)啟或關(guān)閉某個(gè)斷點(diǎn)。
如下圖

lldb_breakpoint1.png

斷點(diǎn)

斷點(diǎn)相關(guān)的打算單獨(dú)寫(xiě)個(gè)帖子糕非,我使用 Xcode 的斷點(diǎn)蒙具,感覺(jué)比 lldb 命令方便點(diǎn)。

更新 UI

使用 recursiveDescription 方法可以遞歸返回指定 view 的層次結(jié)構(gòu)朽肥,如下圖

lldb_ recursiveDescription.png

注意:recursiveDescription 方法是系統(tǒng)私有方法禁筏,需要手敲,不會(huì)有代碼提示衡招。
根據(jù)上面的方法篱昔,我們可以通過(guò)某個(gè) view 的地址獲取該 view,然后在調(diào)試器中改變它的顏色或其他一些屬性始腾。

// 獲取 view 的層次結(jié)果
po [self.view recursiveDescription]
<UIView: 0x7fcea74069a0; frame = (0 0; 428 926); autoresize = W+H; layer = <CALayer: 0x600001a38ec0>>
   | <UILabel: 0x7fcea7407db0; frame = (100 100; 100 30); text = 'lldb調(diào)試器'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x60000393c140>>
   | <UIButton: 0x7fcea9008740; frame = (100 150; 150 30); opaque = NO; layer = <CALayer: 0x600001a0aba0>>
   |    | <UIButtonLabel: 0x7fcea7616950; frame = (10.6667 4; 129 22); text = '這是一個(gè)button'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x600003932a80>>

// 獲取 view 的指定子視圖 label
(lldb) e id $label1 = (id)0x7fcea7407db0
// 設(shè)置 label 的背景色
(lldb) e (void)[$label1 setBackgroundColor:[UIColor yellowColor]]
// 設(shè)置 label text 屬性
(lldb) e (void)[$label1 setText:@"在lldb調(diào)試器中更新 UI"]
// Continue program execution(點(diǎn)擊控制臺(tái)上方工具欄的過(guò)斷點(diǎn)按鈕)繼續(xù)運(yùn)行程序
(lldb) c

在 lldb 調(diào)試器中運(yùn)行上面的一系列命令后可以看到界面確實(shí)發(fā)生了變化州刽,如下圖

lldb_update_UI2.png

這種情況是只有程序繼續(xù)運(yùn)行才能看到界面的變化,因?yàn)楦淖兊膬?nèi)容必須發(fā)送到渲染服務(wù)中才會(huì)顯示更新浪箭。
渲染服務(wù)實(shí)際上是一個(gè)另外的進(jìn)程 (被稱作 backboardd)穗椅。這就是說(shuō)即使我們正在調(diào)試的內(nèi)容所在的進(jìn)程被打斷了,backboardd 也還是繼續(xù)運(yùn)行著的奶栖。
這意味著你可以運(yùn)行下面的命令房待,而不用繼續(xù)運(yùn)行程序:

(lldb) e (void)[CATransaction flush]

此時(shí)你仍然在調(diào)試器中,但是界面會(huì)實(shí)時(shí)更新驼抹。

頁(yè)面跳轉(zhuǎn)

我們可以使用 lldb 調(diào)試器在控制臺(tái)通過(guò)命令實(shí)現(xiàn) push 跳轉(zhuǎn)

// 創(chuàng)建跳轉(zhuǎn)目的地
(lldb) e id $vc = [[ViewController1 alloc] init]
(lldb) p self
(ViewController *) $1 = 0x00007fec5e808f60
// 執(zhí)行跳轉(zhuǎn)
(lldb) e (void)[self.navigationController pushViewController:$vc animated:YES]
// 將跳轉(zhuǎn)過(guò)程渲染到界面顯示
(lldb) e [CATransaction flush]
(lldb) 
// 執(zhí)行 pop
(lldb) e (void)[self.navigationController popViewControllerAnimated:YES]
// 渲染--但是不好用,需要點(diǎn)擊繼續(xù)運(yùn)行結(jié)束調(diào)試或者輸入命令 `c` 結(jié)束調(diào)試才能執(zhí)行 pop拜鹤。
(lldb) e [CATransaction flush]
// 測(cè)試中發(fā)現(xiàn) present 跳轉(zhuǎn)也需要輸入命令 `c`(繼續(xù)運(yùn)行結(jié)束調(diào)試)才好用框冀。

參考
http://www.reibang.com/p/c3d405e7d3a8

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市敏簿,隨后出現(xiàn)的幾起案子明也,更是在濱河造成了極大的恐慌,老刑警劉巖惯裕,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件温数,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡蜻势,警方通過(guò)查閱死者的電腦和手機(jī)撑刺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)握玛,“玉大人够傍,你說(shuō)我怎么就攤上這事甫菠。” “怎么了冕屯?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵寂诱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我安聘,道長(zhǎng)痰洒,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任浴韭,我火速辦了婚禮丘喻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘囱桨。我一直安慰自己仓犬,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布舍肠。 她就那樣靜靜地躺著搀继,像睡著了一般。 火紅的嫁衣襯著肌膚如雪翠语。 梳的紋絲不亂的頭發(fā)上叽躯,一...
    開(kāi)封第一講書(shū)人閱讀 52,156評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音肌括,去河邊找鬼点骑。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谍夭,可吹牛的內(nèi)容都是我干的黑滴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼紧索,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼袁辈!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起珠漂,我...
    開(kāi)封第一講書(shū)人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤晚缩,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后媳危,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體荞彼,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年待笑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鸣皂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖签夭,靈堂內(nèi)的尸體忽然破棺而出齐邦,到底是詐尸還是另有隱情,我是刑警寧澤第租,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布措拇,位于F島的核電站,受9級(jí)特大地震影響慎宾,放射性物質(zhì)發(fā)生泄漏丐吓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一趟据、第九天 我趴在偏房一處隱蔽的房頂上張望券犁。 院中可真熱鬧,春花似錦汹碱、人聲如沸粘衬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)稚新。三九已至,卻和暖如春跪腹,著一層夾襖步出監(jiān)牢的瞬間褂删,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工冲茸, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屯阀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓轴术,卻偏偏與公主長(zhǎng)得像难衰,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逗栽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 相信大家肯定都有過(guò)為了調(diào)試而添加打印變量召衔,或者使用直接常量代替函數(shù)調(diào)用結(jié)果,或者更改判斷條件以進(jìn)入某特定分支的調(diào)試...
    縱橫而樂(lè)閱讀 1,961評(píng)論 0 3
  • 你是否曾經(jīng)苦惱于理解你的代碼祭陷,而去嘗試打印一個(gè)變量的值? NSLog(@"%@", whatIsInsideThi...
    paraneaeee閱讀 1,194評(píng)論 0 7
  • 你是否曾經(jīng)苦惱于理解你的代碼趣席,而去嘗試打印一個(gè)變量的值兵志? NSLog(@"%@", whatIsInsideThi...
    木易林1閱讀 956評(píng)論 0 4
  • 對(duì)于LLDB調(diào)試相信很多開(kāi)發(fā)者都不陌生但是也僅僅停留在下斷點(diǎn)看數(shù)據(jù)的階段,使用最多的命令也就是po甚至包括我在內(nèi)的...
    初光夫閱讀 1,271評(píng)論 2 51
  • 一般我們?cè)趯?xiě)代碼的時(shí)候宣肚,運(yùn)行和調(diào)試使用的都是Xcode想罕,但是要想通過(guò)這種方式調(diào)試程序,我們必須要有程序的源代碼才可...
    Miss_QL閱讀 1,970評(píng)論 0 3