和 LLDB 調(diào)試器來(lái)一場(chǎng)說(shuō)跳就跳的華爾茲(一)

序:原文 Dancing in the Debugger — A Waltz with LLDB
聲明:譯文有一部分參考自:與調(diào)試器共舞 - LLDB 的華爾茲


前言

你是否曾經(jīng)為試圖理解尼的代碼和打印一個(gè)變量的值而感到苦惱靴寂?

NSLog(@"%@", whatIsInsideThisThing);

或者跳過(guò)一個(gè)函數(shù)調(diào)用來(lái)簡(jiǎn)化程序的行為?

NSNumber *n = @7; // theFunctionThatShouldReallyBeCalled();

或短路一個(gè)邏輯檢查?

if (1 || theBooleanAtStake) { ... }

抑或偽造一個(gè)函數(shù)的實(shí)現(xiàn)?

int calculateTheTrickyValue {
  return 9;

  /*
   Figure this out later.
   ...
}

并且每次都必須重新編譯只锭,重新運(yùn)行嗎?

構(gòu)建軟件是復(fù)雜的叶沛,并且bug總是會(huì)出現(xiàn)图贸。常見(jiàn)的修復(fù)周期是修改代碼新症,編譯罢低,再次運(yùn)行坯钦,并希望變的最好。

其實(shí)并不需要這樣益咬。您可以使用調(diào)試器哈!即使你已經(jīng)知道如何使用調(diào)試器來(lái)檢查一個(gè)變量,可是調(diào)試器可以做的遠(yuǎn)不止這些幽告。

本文打算挑戰(zhàn)你對(duì)調(diào)試的認(rèn)知梅鹦,更詳細(xì)地解釋了一些你可能不知道的基本原理,然后給你展示一些有趣的例子冗锁。讓我們隨著舞曲開(kāi)始旋轉(zhuǎn)起來(lái)齐唆,看看我們會(huì)以何種水平結(jié)束。

LLDB

LLDB 是一個(gè)有著 REPL 特性冻河,并內(nèi)置 C++Python 插件的開(kāi)源調(diào)試器箍邮。該調(diào)試器捆綁在Xcode內(nèi)部,并內(nèi)置于Xcode窗口底部的控制臺(tái)面板里叨叙。調(diào)試器允許您在程序運(yùn)行的特定時(shí)刻暫停程序锭弊,來(lái)檢查變量的值,執(zhí)行自定義的指令擂错,然后按照你所認(rèn)為合適的步驟來(lái)操作程序的進(jìn)展味滞。(這里 是調(diào)試器如何工作的大體介紹。)

之前尼很有可能使用過(guò)調(diào)試器钮呀,即使只是在Xcode窗口頁(yè)面添加斷點(diǎn)剑鞍。但是有一些小竅門(mén),可以使你有一些很漂亮而又酷爽的事情去做爽醋。GDB to LLDB 參考的是一個(gè)偉大的可用命令的鳥(niǎo)瞰圖蚁署,你還有可能想要安裝 Chisel ,一個(gè)可以使調(diào)試器更加有趣的 LLDB 插件的開(kāi)源合輯蚂四。

與此同時(shí)光戈,讓我們以 在調(diào)試器中如何打印一個(gè)變量的值 來(lái)開(kāi)始這場(chǎng)華爾茲的旅程吧。

基礎(chǔ)知識(shí)

這里是一段打印一個(gè)字符串的簡(jiǎn)單示例小程序证杭。注意田度,在第16行添加了一個(gè)斷點(diǎn):

斷點(diǎn)的示例小程序

程序會(huì)在第16行被暫停運(yùn)行,并且控制臺(tái)會(huì)被打開(kāi)解愤,允許我們和調(diào)試器交互镇饺。那我們應(yīng)該輸入些什么呢?

help

最簡(jiǎn)單的命令是 help 送讲,這一指令將會(huì)列出所有的命令奸笤。如果你忘記某條命令是做什么的或者想了解更多的命令,你可以使用 help 命令查看更多的細(xì)節(jié)哼鬓,例如 help printhelp thread 监右。如果你忘記了 help 命令是做什么的?你可以使用 help help 命令异希,但如果你知道的足夠多健盒,也許你還沒(méi)有完全忘記命令是做什么的。

print

使用 print 命令打印一個(gè)值是很簡(jiǎn)單的。

print 的使用

LLDB 實(shí)際上會(huì)做前綴匹配扣癣,因此尼也可以使用 prin 惰帽、 prip 命令父虑,但是不可以使用 pr 该酗,因?yàn)?LLDB 不能把它和 process 命令做區(qū)分(幸運(yùn)的是,p 并沒(méi)有歧義)士嚎。
你可能還會(huì)注意到呜魄,結(jié)果中有個(gè) $0。實(shí)際上你可以使用它來(lái)代指這個(gè)結(jié)果莱衩。試試 print $0 + 7爵嗅,你會(huì)看到 45。任何以美元符開(kāi)頭的東西都是存在于 LLDB 的命名空間的膳殷,它們是為了幫助你進(jìn)行調(diào)試而存在的操骡。

expression

如果想修改一個(gè)值怎么辦?這里使用 expression 命令赚窃。

expression

這一命令不僅僅修改了調(diào)試器中的值册招,實(shí)際上還修改了程序中的值。如果你在這個(gè)基礎(chǔ)上繼續(xù)執(zhí)行程序勒极,將會(huì)打印83 huang qimeng是掰,神奇吧!
從現(xiàn)在開(kāi)始辱匿,我們下面會(huì)使用這兩個(gè)命令的簡(jiǎn)化形式 p键痛、 e

什么是 print 命令

這里有一個(gè)有趣的表達(dá)式:p count = 18匾七,如果我們執(zhí)行這個(gè)命令并打印count的值絮短,我們會(huì)看到結(jié)果和這個(gè)表達(dá)式 expression count = 18 是一個(gè)吊樣的。

expression不同的是昨忆,print不需要參數(shù)丁频,比如e -h +17到底是以-h為標(biāo)識(shí),僅僅執(zhí)行+17呢邑贴,還是計(jì)算17h的差值呢席里?連字符確實(shí)讓人困惑,你可能得不到尼想要的結(jié)果拢驾。

幸運(yùn)的是解決方式很簡(jiǎn)單奖磁,使用--表示標(biāo)識(shí)的結(jié)束,和輸入的開(kāi)始繁疤,比如以-h作為標(biāo)識(shí)咖为,就要用e -h -- +17秕狰,如果想計(jì)算它們的差值,就使用e -- -h +17躁染,一般來(lái)說(shuō)封恰,不使用標(biāo)識(shí)的情況比較普遍,所以e --就有了一個(gè)簡(jiǎn)寫(xiě)的方式褐啡,即print

輸入help print鳖昌,然后向下滾動(dòng)备畦,就會(huì)發(fā)現(xiàn):

'print' is an abbreviation for 'expression --'.
(print是 `expression --` 的簡(jiǎn)寫(xiě))

打印對(duì)象

輸入:

p objects

然后輸出是一堆奇怪的東西:

(NSString *) $7 = 0x0000000104da4040 @"huang qimeng"

如果我們嘗試打印結(jié)構(gòu)更復(fù)雜的對(duì)象,結(jié)果甚至?xí)悖?/p>

(lldb) p @[ @"foo", @"bar" ]

(NSArray *) $8 = 0x00007fdb9b71b3e0 @"2 objects"

實(shí)際上许昨,我們想看的是對(duì)象的 description 方法的結(jié)果懂盐。我么需要使用 -O (注意是字母 O,而不是數(shù)字 0) 標(biāo)志告訴expression 命令以對(duì)象 (Object) 的方式來(lái)打印結(jié)果糕档。

(lldb) e -O -- $8
<__NSArrayI 0x7fdb9b71b3e0>(
foo,
bar
)

幸運(yùn)的是莉恼,e -o --也有個(gè)別名,即poprint object的縮寫(xiě))速那,我們可以這樣使用:

(lldb) po $8
<__NSArrayI 0x7fdb9b71b3e0>(
foo,
bar
)
(lldb) po @"lunar"
lunar
(lldb) p @"lunar"
(NSString *) $13 = 0x00007fdb9d0003b0 @"lunar"

打印變量

可以為print指定不同的打印格式俐银。他們都以print/<fmt>或者簡(jiǎn)化的p/<fmt>格式書(shū)寫(xiě)。例子如下:
默認(rèn)格式:

(lldb) p 16
16

十六進(jìn)制:

(lldb) p/x 16
0x10

二進(jìn)制(t代表two):

(lldb) p/t 16
0b00000000000000000000000000010000
(lldb) p/t (char)16
0b00010000

你也可以使用p/c打印字符端仰,或者p/s打印以空終止的字符串*char **捶惜,這里是輸出格式的完整說(shuō)明。

變量

現(xiàn)在你已經(jīng)可以打印對(duì)象和簡(jiǎn)單類型的變量了荔烧,以及如何使用expression命令在調(diào)試器中修改他們了吱七。~~此處廢話不翻譯~~,不過(guò)為了能使用聲明的變量鹤竭,變量必須以美元符號(hào)$開(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

糟了~,LLDB無(wú)法分辨涉及的類型(注:返回的類型)臀稚,這種事情經(jīng)常出現(xiàn)吝岭,給個(gè)說(shuō)明就好了:

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

變量使調(diào)試器的使用變得更容易了,你想不到吧烁涌???

未完待續(xù)...

移步 和 LLDB 調(diào)試器來(lái)一場(chǎng)說(shuō)跳就跳的華爾茲(二)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末苍碟,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子撮执,更是在濱河造成了極大的恐慌微峰,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抒钱,死亡現(xiàn)場(chǎng)離奇詭異蜓肆,居然都是意外死亡颜凯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門(mén)仗扬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)症概,“玉大人,你說(shuō)我怎么就攤上這事早芭”顺牵” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵退个,是天一觀的道長(zhǎng)募壕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)语盈,這世上最難降的妖魔是什么舱馅? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮刀荒,結(jié)果婚禮上代嗤,老公的妹妹穿的比我還像新娘。我一直安慰自己缠借,他們只是感情好干毅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著泼返,像睡著了一般溶锭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上符隙,一...
    開(kāi)封第一講書(shū)人閱讀 51,775評(píng)論 1 307
  • 那天趴捅,我揣著相機(jī)與錄音,去河邊找鬼霹疫。 笑死拱绑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丽蝎。 我是一名探鬼主播猎拨,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼屠阻!你這毒婦竟也來(lái)了红省?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤国觉,失蹤者是張志新(化名)和其女友劉穎吧恃,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體麻诀,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痕寓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年傲醉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呻率。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡硬毕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出礼仗,到底是詐尸還是另有隱情吐咳,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布元践,位于F島的核電站挪丢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏卢厂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一惠啄、第九天 我趴在偏房一處隱蔽的房頂上張望慎恒。 院中可真熱鬧,春花似錦撵渡、人聲如沸融柬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)粒氧。三九已至,卻和暖如春节腐,著一層夾襖步出監(jiān)牢的瞬間外盯,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工翼雀, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饱苟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓狼渊,卻偏偏與公主長(zhǎng)得像箱熬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狈邑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

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