iOS調(diào)試-LLDB學(xué)習(xí)總結(jié)

Xcode的使用中總是離不開調(diào)試這個環(huán)境,在一年多的iOS開發(fā)時間中件缸,我更多地依賴于XCode本身提供的GUI工具來進行調(diào)試,而對LLDB敬而遠(yuǎn)之种樱,這段時間好好學(xué)習(xí)了LLDB的使用荆萤,發(fā)覺我錯過了太多東西了……因此做一個比較完備的總結(jié)颠通,也希望在寫這篇文章的過程中進一步學(xué)習(xí)LLDB調(diào)試的各種實踐方法称诗。

LLDB闡述

LLDB 是一個有著 REPL 的特性和 C++ ,Python 插件的開源調(diào)試器蒸痹。LLDB 綁定在 Xcode 內(nèi)部僻爽,存在于主窗口底部的控制臺中虫碉。調(diào)試器允許你在程序運行的特定時暫停它,你可以查看變量的值胸梆,執(zhí)行自定的指令敦捧,并且按照你所認(rèn)為合適的步驟來操作程序的進展。(摘自 與調(diào)試器共舞)

它的基本語法為

<command> [<subcommand> [<subcommand>...]] <action> [-options [option-value]] [argument [argument...]]

在XCode中碰镜,我們需要在程序暫停進入調(diào)試狀態(tài)時才能使用LLDB兢卵,可以通過breakpoint、watchpoint绪颖、或者XCode的調(diào)試臺自帶的暫停按鈕使程序暫停秽荤。

快捷鍵

為了方便查詢,就直接在文章開頭po出常用的快捷鍵菜單把~

快捷鍵功能 命令
暫停/繼續(xù) cmd + ctrl + Y
控制臺顯示/隱藏 cmd + Y
光標(biāo)切換到控制臺 cmd + shift + C
清空控制臺 cmd + K
step over F6
step into F7
step out F8

HELP

LLDB的入門與Linux命令入門類似柠横,可以通過執(zhí)行help命令來查詢這個命令的意義和詳細(xì)參數(shù)

從描述中我們能看出thread backtrace是用來查詢暫停時的線程堆棧的窃款,并了解了可以帶入的入?yún)ⅰ?/p>

唯一匹配原則

LLDB有個很省事的特性,如果輸入的字母已經(jīng)能匹配到某個命令牍氛,就可以直接執(zhí)行晨继,等于輸入了完整的命令。

可以看到expressione是等價的

變量查詢與修改

  1. expression

    expression 可簡寫為e搬俊,作用為執(zhí)行一個表達式紊扬,首當(dāng)其沖曲饱,它肯定可以用來查詢當(dāng)前堆棧變量的值。

    當(dāng)然e的更主要的用法是通過執(zhí)行表達式珠月,動態(tài)修改當(dāng)前線程堆棧變量的值,從而達到調(diào)試的目的(其實查詢也很主要楔敌,只是會用另一種方式查詢)啤挎。
    比如,我們可以在某個if..else..的語句前打上斷點卵凑,直接修改條件表達式的值庆聘,使程序覆蓋了不同分支,而不用苦心積慮地停止程序勺卢、hard code變量值來進行調(diào)試伙判,節(jié)省了一大坨修改與編譯時間。

在上面這份測試代碼黑忱,在進入條件判斷語句前打了斷點宴抚,那我們可以通過e命令,來自由控制程序走向任何一個分支甫煞。

我們也可以通過執(zhí)行表達式菇曲,實時改變當(dāng)前的UI界面,方便界面代碼的調(diào)試抚吠,比如我們可以執(zhí)行下面代碼來改變當(dāng)前UI常潮,讓cellItem的邊框顯示出來,以判斷我們的界面布局是否正確楷力。
e @import UIKit
e cellItem.layer.borderWidth = 1
這里有個特殊的問題喊式,由于程序已經(jīng)被斷點暫停了,因此執(zhí)行UI更新的線程也被暫停了萧朝。我們可以通過讓程序繼續(xù)運行岔留,也可以通過另一條表達式來更新UI。
e (void)[CATransaction flush]

> 我們也可以用 `call` 來代替 `expression --`剪勿,其實我覺得用`e`更方便贸诚。 =。=
  1. p厕吉、po

    在上面說過酱固,在調(diào)試中,我們一般用e命令來修改變量头朱,而查詢變量一般用ppo命令运悲。
    po的作用為打印對象,事實上项钮,我們可以通過help po得知班眯,poexpression -O --的簡寫希停,我們可以通過它打印出對象,而不是打印對象的指針署隘。而值得一提的是宠能,在 help expression 返回的幫助信息中,我們可以知道磁餐,po命令會嘗試調(diào)用對象的 description 方法來取得對象信息违崇,因此我們也可以重載某個對象的description方法,使我們調(diào)試的時候能獲得可讀性更強诊霹,更全面的信息羞延。

    -(NSString*)description
    {
        return [NSString stringWithFormat:@"Portal[%@, %@, %@, %@, %@, %@, %@]", ssid, mpUrl, ticket, authUrl, _openid, _tid, extend];
    }
    

    p即是print,也是expression --的縮寫脾还,與po不同伴箩,它不會打出對象的詳細(xì)信息,只會打印出一個$符號鄙漏,數(shù)字嗤谚,再加上一段地址信息。由于po命令下怔蚌,對象的description 有可能被隨便亂改呵恢,沒有輸出地址消息。

$符號在LLDB中代表著變量的分配媚创。每次使用p后渗钉,會自動為你分配一個變量,后面再次想使用這個變量時钞钙,就可以直接使用鳄橘。我們可以直接使用這個地址做一些轉(zhuǎn)換,獲取對象的信息

斷點

  1. breakpoint
    所有調(diào)試都是由斷點開始的芒炼,我們接觸的最多瘫怜,就是以breakpoint命令為基礎(chǔ)的斷點。
    一般我們對breakpoint命令使用得不多本刽,而是在XCode的GUI界面中直接添加斷點鲸湃。除了直接觸發(fā)程序暫停供調(diào)試外,我們可以進行進一步的配置子寓。
  • 添加condition暗挑,一般用于多次調(diào)用的函數(shù)或者循壞的代碼中,在作用域內(nèi)達到某個條件斜友,才會觸發(fā)程序暫停
  • 忽略次數(shù)炸裆,這個很容易理解,在忽略觸發(fā)幾次后再觸發(fā)暫停
  • 添加Action鲜屏,為這個斷點添加子命令烹看、腳本国拇、shell命令、聲效(有個毛線用)等Action惯殊,我的理解是一個腳本化的功能酱吝,我們可以在斷點的基礎(chǔ)上添加一些方便調(diào)試的腳本,提高調(diào)試效率土思。
  • 自動繼續(xù)掉瞳,配合上面的添加Action,我們就可以不用一次又一次的暫停程序進行調(diào)試來查詢某些值(大型程序中斷一次還是會有卡頓)浪漠,直接用Action將需要的信息打印在控制臺,一次性查看即可霎褐。

除去在代碼中直接點擊添加斷點外址愿,我們也可以在 command + 7 breakpoint頁面下直接添加相關(guān)的斷點。我們常用的有 Exception Breakpoint 與 Symbolic Breakpoint

  • Add Exception Breakpoint
    Exception Breakpoint為異常斷點冻璃。在某些情況下响谓,TableView的數(shù)據(jù)源與UI操作不一致,或者容器插入了nil的指針省艳,將消息傳至野指針娘纷,都會導(dǎo)致程序的crash,并且LLDB輸出的信息不是很友好跋炕。加上異常斷點赖晶,能夠使程序在拋出異常的棧自動暫停,可直接定位導(dǎo)致拋出異常的代碼辐烂。在一般的開發(fā)流程中遏插,都建議開啟這個異常斷點,反正你總是會crash的嘿嘿纠修。
  • Add Symbolic Breakpoint
    Symbolic Breakpoint 為符號斷點胳嘲。有時候,我們并不清楚程序會在什么情況下調(diào)用某一個函數(shù)扣草,那我們可以通過符號斷點來獲取調(diào)用該函數(shù)時的程序堆棧了牛。當(dāng)然,在自己實現(xiàn)的類辰妙,我們也可以在該函數(shù)實現(xiàn)的地方打上斷點鹰祸,但如果需要定位其他框架提供的API的調(diào)用,就只能使用符號斷點啦密浑。

當(dāng)然福荸,LLDB的breakpoint命令也可以實現(xiàn)上述的功能,因為不常用肴掷,所以這里就簡單列舉一些用法敬锐。 breakpoint set -n trigger //在所有類的trigger函數(shù)實現(xiàn)中打上斷點

    breakpoint set -f ViewController.m -n trigger //在ViewController.m中的trigger方法打上斷點 
    breakpoint set -f ViewController.m -l 50 //在ViewController.m的50行打上斷點 
    breakpoint set -f ViewController.m -n trigger: -c testCondition > 5 //在ViewController.m中的trigger方法打上斷點并添加condition背传, testCondition大于5時觸發(fā)斷點 
    breakpoint set -n trigger -o //單次斷點 
    breakpoint command add -o "frame info" 3 //在設(shè)置的三號斷點加入子命令frame info 
    breakpoint list // 列出所有斷點 
    breakpoint delete 3 //刪除3號斷點
  1. watchpoint

有時候我們會關(guān)心類的某個屬性什么時候被人修改了,最簡單的方法當(dāng)然就是在setter的方法打斷點台夺,或者在@property的屬性生命行打上斷點径玖。這樣當(dāng)對象的setter方法被調(diào)用時,就會觸發(fā)這個斷點颤介。


當(dāng)然這么做是有缺點的梳星,對于直接訪問內(nèi)存地址的修改,setter方法的斷點并沒有辦法監(jiān)控得到滚朵,因此我們需要用到watchpoint命令冤灾。
watchpoint命令在XCode的GUI中也可以直接使用,當(dāng)程序暫停時辕近,我們能對當(dāng)前程序棧中的變量設(shè)置watchpoint韵吨。值得注意的是,watchpoint是直接設(shè)置到該變量所在的內(nèi)存地址上的移宅,所以當(dāng)這個變量釋放了后归粉,watchpoint仍然是對這個地址的內(nèi)存生效的。

我們也可以在LLDB中直接用watchpoint命令漏峰,可以通過選項實現(xiàn)更多效果糠悼。

    watchpoint set self->testVar     //為該變量地址設(shè)置watchpoint
    watchpoint set expression 0x00007fb27b4969e0 //為該內(nèi)存地址設(shè)置watchpoint,內(nèi)存地址可從前文提及的`p`命令獲取
    watchpoint command add -o 'frame info' 1  //為watchpoint 1號加上子命令 `frame info`
    watchpoint list //列出所有watchpoint
    watchpoint delete // 刪除所有watchpoint

堆棧

  1. threadbt

bt即是thread backtrace浅乔,作用是打印出當(dāng)前線程的堆棧信息倔喂。當(dāng)程序發(fā)生了crash后,我們可以用該命令打印出發(fā)生crash的當(dāng)前的程序堆棧靖苇,查詢出發(fā)生crash的調(diào)用路徑滴劲。由于比較常用,所以LLDB直接給它一個特殊的bt別名顾复。
thread另一個比較常用的用法是 thread return班挖,調(diào)試的時候,我們希望在當(dāng)前執(zhí)行的程序堆棧直接返回一個自己想要的值芯砸,可以執(zhí)行該命令直接返回萧芙。
thread return <expr>
在這個斷點中,我們可以執(zhí)行 thread return NO讓該函數(shù)調(diào)用直接返回NO 假丧,在調(diào)試中輕松覆蓋任何函數(shù)的返回路徑双揪。

  1. frame

frame即是幀,其實就是當(dāng)前的程序堆棧包帚,我們輸入bt命令渔期,打印出來的其實是當(dāng)前線程的frame。
在調(diào)試中,一般我們比較關(guān)心當(dāng)前堆棧的變量值疯趟,我們可以使用frame variable來獲取全部變量值拘哨。當(dāng)然也可以輸入特定變量名,來獲取單獨的變量值信峻,如frame v self-> testVar來獲取testVar的值倦青。

End

全文暫時完~在接下來的實踐與學(xué)習(xí)中,如果有好玩的新東西盹舞,也會補充到這里來产镐。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市踢步,隨后出現(xiàn)的幾起案子癣亚,更是在濱河造成了極大的恐慌,老刑警劉巖获印,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件述雾,死亡現(xiàn)場離奇詭異,居然都是意外死亡蓬豁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門菇肃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來地粪,“玉大人,你說我怎么就攤上這事琐谤◇〖迹” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵斗忌,是天一觀的道長质礼。 經(jīng)常有香客問我,道長织阳,這世上最難降的妖魔是什么眶蕉? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮唧躲,結(jié)果婚禮上造挽,老公的妹妹穿的比我還像新娘。我一直安慰自己弄痹,他們只是感情好饭入,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肛真,像睡著了一般谐丢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天乾忱,我揣著相機與錄音讥珍,去河邊找鬼。 笑死饭耳,一個胖子當(dāng)著我的面吹牛串述,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寞肖,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纲酗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了新蟆?” 一聲冷哼從身側(cè)響起觅赊,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎琼稻,沒想到半個月后吮螺,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡帕翻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年鸠补,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘀掸。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡紫岩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出睬塌,到底是詐尸還是另有隱情泉蝌,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布揩晴,位于F島的核電站勋陪,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏硫兰。R本人自食惡果不足惜诅愚,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劫映。 院中可真熱鬧呻粹,春花似錦、人聲如沸苏研。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摹蘑。三九已至筹燕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背撒踪。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工过咬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人制妄。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓掸绞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親耕捞。 傳聞我的和親對象是個殘疾皇子衔掸,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

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

  • 轉(zhuǎn)載 與調(diào)試器共舞 - LLDB 的華爾茲: https://objccn.io/issue-19-2/ 推薦:i...
    F麥子閱讀 3,333評論 0 10
  • LLDB的Xcode默認(rèn)的調(diào)試器,它與LLVM編譯器一起俺抽,帶給我們更豐富的流程控制和數(shù)據(jù)檢測的調(diào)試功能敞映。平時用Xc...
    CoderSC閱讀 1,361評論 0 2
  • 你是否曾經(jīng)苦惱于理解你的代碼,而去嘗試打印一個變量的值磷斧? NSLog(@"%@", whatIsInsideThi...
    木易林1閱讀 955評論 0 4
  • 你是否曾經(jīng)苦惱于理解你的代碼振愿,而去嘗試打印一個變量的值? NSLog(@"%@", whatIsInsideThi...
    paraneaeee閱讀 1,194評論 0 7
  • 【讀經(jīng)】 詩篇36 【金句】 神啊弛饭,你的慈愛何其寶貴冕末!世人投靠在你翅膀的蔭下。(詩篇 36:7 和合本) 【感動】...
    chanor閱讀 944評論 0 0