lldb的Xcode默認(rèn)的調(diào)試器捏鱼,它與LLVM編譯器一起芹啥,帶給我們更豐富的流程控制和數(shù)據(jù)檢測(cè)的調(diào)試功能。平時(shí)用Xcode運(yùn)行程序凡简,實(shí)際走的都是lldb纱兑。熟練使用lldb呀闻,可以讓你debug事半功倍
lldb 用法
首先在應(yīng)用程序內(nèi)打斷點(diǎn)。
接下來(lái)一個(gè)一個(gè)的去介紹和使用潜慎。-
apropos :調(diào)試器命令列表相關(guān)的詞或主題
語(yǔ)法:apropos <search-word>
作用:輸出你想要搜索的關(guān)鍵詞的相關(guān)內(nèi)容捡多。
例子:apropos log
結(jié)果: -
breakpoint :命令操作斷點(diǎn)
語(yǔ)法:breakpoint <subcommand> [<command-options>]
作用:可以通過(guò)命令來(lái)對(duì)斷點(diǎn)進(jìn)行增加、刪除等操作铐炫。
一些子命令如下:
1垒手、clear:刪除或禁用斷點(diǎn)匹配指定的源文件和行。
2倒信、command:命令添加,刪除和清單LLDB命令在遇到斷點(diǎn)時(shí)執(zhí)行科贬。
3、delete:刪除指定的斷點(diǎn)(s)。如果沒(méi)有斷點(diǎn)指定,刪除它們榜掌。
4优妙、disable:禁用指定斷點(diǎn)(s),而不刪除它們。如果沒(méi)有指定,禁用所有斷點(diǎn)憎账。
5套硼、enable:使指定的禁用斷點(diǎn)(s)。如果沒(méi)有斷點(diǎn)指定,使所有的人胞皱。
6邪意、list:列舉一些或所有斷點(diǎn)配置的詳細(xì)級(jí)別。
7反砌、modify:修改選項(xiàng)斷點(diǎn)或設(shè)置的斷點(diǎn)可執(zhí)行文件雾鬼。如果沒(méi)有指定斷點(diǎn),作用于最后創(chuàng)建斷點(diǎn)。
8于颖、name:命令來(lái)管理斷點(diǎn)的名字標(biāo)簽
9呆贿、set:設(shè)置一個(gè)斷點(diǎn)或設(shè)置斷點(diǎn)的可執(zhí)行文件嚷兔。
例子:通過(guò) breakpoint 來(lái)添加森渐、刪除以及查找斷點(diǎn)。
查看當(dāng)前斷點(diǎn)列表
![查看當(dāng)前斷點(diǎn)列表.png](http://upload-images.jianshu.io/upload_images/1622166-558a9f2f240b583c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
紅色框框里面表示斷點(diǎn)的行數(shù)冒晰⊥拢可以看出來(lái)現(xiàn)在也就只有2個(gè)斷點(diǎn),一個(gè)在73行壶运,一個(gè)在80行耐齐。
- 添加一個(gè)95行的斷點(diǎn)
breakpoint set -f ViewController.m -l 95
-f 后面的是文件名 -l 后面是行數(shù)
- 再次查看當(dāng)前斷點(diǎn)列表
![再次查看斷點(diǎn)列表.png](http://upload-images.jianshu.io/upload_images/1622166-5fe514ad42966a48.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 刪除 80 行的斷點(diǎn)
breakpoint clear -f ViewController.m -l 80
- 結(jié)果列表中就沒(méi)有 80 行的斷點(diǎn)信息了。
![最后的斷點(diǎn)列表.png](http://upload-images.jianshu.io/upload_images/1622166-790ba6f138a700a7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
bugreport :命令來(lái)創(chuàng)建特定于域的bug報(bào)告
語(yǔ)法:bugreport <subcommand> [<subcommand-options>]
作用:創(chuàng)建一份 bug 報(bào)告
例子:
bug report unwind XXX(XXX 是你想看的方法名)
結(jié)果會(huì)輸出一堆東西蒋情。you can try埠况!-
command :管理自定義命令LLDB命令(創(chuàng)建別名)
語(yǔ)法:command <subcommand> [<subcommand-options>]
一些子命令:
1、alias:定義一個(gè)自定義命令
2棵癣、delete:刪除一個(gè)或多個(gè)自定義命令的命令
3辕翰、history:當(dāng)前執(zhí)行的歷史命令
4、regex:定義一個(gè)現(xiàn)有命令的自定義命令
5狈谊、script:來(lái)管理自定義命令實(shí)現(xiàn)的腳本解釋器
6喜命、source:從文件讀取和執(zhí)行命令LLDB
7、unalias:刪除一個(gè)或多個(gè)自定義命令定義為“命令別名”
例子:
想知道你執(zhí)行 LLDB 幾條命令河劝,輸入
command history
還有個(gè)實(shí)用的例子:
比如上面的添加斷點(diǎn)命令過(guò)長(zhǎng)壁榕,那么我們可以這樣做。
command alias bkt breakpoint set -f %1 -l %2
然后再添加斷點(diǎn)赎瞎。
bkt ViewController.m 90
你看結(jié)果會(huì)發(fā)現(xiàn)已經(jīng)添加上了牌里,是不是很方便?
如果不想要這個(gè)別名了就可以執(zhí)行下列命令把它給刪除务甥。
command unaries but -
disassemble :拆卸指定的指令
語(yǔ)法:disassemble [<cmd-options>]
例子:
disassemble -b
這樣會(huì)顯示你當(dāng)前斷點(diǎn)所在的方法內(nèi)所有的操作碼字節(jié)牡辽。
效果:
紅色框內(nèi)的信息能更好的幫助你調(diào)試程序贪染。
如果你想拆卸某一行可以用下面的命令:
disassemble -c 84(這個(gè)數(shù)字就是你想要拆卸的行數(shù),當(dāng)然了他會(huì)聯(lián)系上下文給你拆卸這個(gè)對(duì)象的信息) expression (我用到的: 修改程序中的代碼)
場(chǎng)景:假設(shè)你程序運(yùn)行后發(fā)現(xiàn)有個(gè)視圖的背景顏色不好看催享,需要改杭隙,好吧,在代碼中改一下因妙,再運(yùn)行痰憎。發(fā)現(xiàn)不好看,再改攀涵。這樣太過(guò)麻煩铣耘,但是我們可以用 expression 來(lái)實(shí)現(xiàn),代碼:
expression imageView.backgroundColor = [UIColor redColor]
然后再運(yùn)行你就會(huì)發(fā)現(xiàn)這個(gè)視圖的顏色變成紅色了以故。不止顏色蜗细,一些數(shù)值也是可以改的。-
frame 命令選擇與當(dāng)前線程的堆棧幀
子命令:
1怒详、info:列表當(dāng)前堆棧幀在當(dāng)前的信息線程
2炉媒、select:選擇當(dāng)前堆棧框架內(nèi)通過(guò)索引當(dāng)前線程
3昆烁、variable:顯示變量當(dāng)前堆棧幀吊骤。默認(rèn)為所有參數(shù)和局部變量的范圍
效果:
1中,箭頭表示的是你斷點(diǎn)所在的位置
后面的就是你所寫的代碼
2中静尼,有你當(dāng)前所在的類的名字白粉,所在方法的方法名以及一些創(chuàng)建的對(duì)象
3中,就是列舉方法名鼠渺,行數(shù)鸭巴,類名等信息。
根據(jù)自己的喜好選擇相應(yīng)的命令拦盹。 quit 退出當(dāng)前的LLDB鹃祖。
register 訪問(wèn)當(dāng)前線程的寄存器和堆棧幀
子命令:
1、read:讀取當(dāng)前的寄存器值當(dāng)前幀
2掌敬、write:修改一個(gè)寄存器值settings 管理 LLDB 的設(shè)置
子命令:
1惯豆、append:將值附加到調(diào)試器里面。數(shù)組奔害、字典或者字符串設(shè)置楷兽。
2、clear:清除調(diào)試器
3华临、insert-after:在指定的元素的索引芯杀,將一個(gè)或多個(gè)值插入一系列調(diào)試器設(shè)置
4、insert-before:在指定的元素的索引,立刻將一個(gè)或多個(gè)值插入一系列調(diào)試器設(shè)置
5揭厚、list:調(diào)試器列表
6却特、remove:移除設(shè)置
7、replace:替換設(shè)置中的值
8筛圆、set:設(shè)置指定的調(diào)試器的設(shè)置值
9裂明、show:顯示調(diào)試器設(shè)置和他們目前的值。source 檢查源代碼所描述的調(diào)試信息當(dāng)前目標(biāo)的過(guò)程
子命令:
1太援、info:顯示一行信息來(lái)源為當(dāng)前目標(biāo)的過(guò)程闽晦。默認(rèn)為當(dāng)前堆棧幀中指令指針
2、list:顯示指定的當(dāng)前目標(biāo)過(guò)程的源代碼-
thread 操作在一個(gè)或多個(gè)線程在當(dāng)前過(guò)程
子命令:
1提岔、backtrace:顯示線程調(diào)用堆棧仙蛉。默認(rèn)為當(dāng)前可以指定線程,線程索引作為參數(shù)。使用thread-index看到所有線程碱蒙。
2荠瘪、continue:繼續(xù)執(zhí)行當(dāng)前目標(biāo)的過(guò)程。
3赛惩、info:顯示一個(gè)擴(kuò)展的總結(jié)一個(gè)或多個(gè)線程哀墓。
4、jump:將程序計(jì)數(shù)器設(shè)置為一個(gè)新的地址坊秸。
5麸祷、list:顯示每個(gè)線程在當(dāng)前目標(biāo)的總結(jié)的過(guò)程澎怒。
6褒搔、plan:管理線程控制計(jì)劃執(zhí)行。
7喷面、return:返回從堆棧幀,短路執(zhí)行更新的框架和選擇屈服指定的值星瘾。
8、select:更改當(dāng)前選中的線程惧辈。
9琳状、step-in:進(jìn)入調(diào)用
10、step-init:?jiǎn)尾秸{(diào)用
11盒齿、step-ints-over:?jiǎn)尾侥畛眩邕^(guò)調(diào)用。
12边翁、step-out:執(zhí)行完當(dāng)前堆棧幀并停止之后返回翎承。
13、step-over:?jiǎn)尾椒遥邕^(guò)調(diào)用叨咖。
14、step-scripted:C中選擇的腳本類。
15甸各、until:到達(dá)到行號(hào)或地址當(dāng)前或指定的線程垛贤,停止時(shí)返回從當(dāng)前函數(shù)作為一種安全措施。
例子:
thread info
-
type 命令操作的類型系統(tǒng)
子命令:- 1??趣倾、category:操作類型分類
- define:定義一個(gè)新的類別
- delete:刪除一個(gè)類別
- disable:禁用一個(gè)類別
- enable:?jiǎn)⒂靡粋€(gè)類別
- list:現(xiàn)有的類別的列表
- 2??聘惦、filter:操作類型過(guò)濾器
- add:添加一個(gè)新的過(guò)濾器的類型
- clear:刪除所有現(xiàn)有的過(guò)濾器
- delete:刪除現(xiàn)有的濾波器類型
- list:顯示當(dāng)前過(guò)濾器的列表
- 3??、format:自定義值顯示格式
- add:添加一個(gè)新的格式類型
- clear:刪除所有現(xiàn)有的格式樣式
- delete:刪除現(xiàn)有的格式風(fēng)格類型
- info:評(píng)估提供的表達(dá)式和顯示格式應(yīng)用于結(jié)果值
- list:顯示當(dāng)前的列表格式
- 4??儒恋、lookup:當(dāng)前查找類型和聲明
- 5??部凑、summary:編輯變量匯總
- add:添加一個(gè)新的匯總的風(fēng)格類型
- clear:刪除所有現(xiàn)有的總結(jié)
- delete:刪除現(xiàn)有的一種總結(jié)類型
- info:評(píng)估提供的表達(dá)式和顯示總結(jié)應(yīng)用結(jié)果值
- list:顯示當(dāng)前的列表格式
- 6??、synthetic:操作合成類型
- add:添加一個(gè)新類型合成提供者
- clear:刪除所有的類型
- delete:刪除現(xiàn)有的一種合成類型
- info:評(píng)估提供的表達(dá)式和顯示總結(jié)應(yīng)用結(jié)果值
- list:顯示當(dāng)前的列表格式
- 1??趣倾、category:操作類型分類
version 顯示調(diào)試器LLDB版本
-
watchpoint 操作檢查點(diǎn)碧浊,檢查內(nèi)存的讀寫涂邀。
- 1??、command:添加,刪除和檢查L(zhǎng)LDB命令當(dāng)監(jiān)視點(diǎn)
- add:添加一組命令LLDB監(jiān)視點(diǎn)
- delete:刪除監(jiān)視點(diǎn)
- list:監(jiān)視點(diǎn)成功的列表
- 2??箱锐、delete:刪除指定的監(jiān)視點(diǎn)
- 3??比勉、disable:禁用指定的監(jiān)視點(diǎn),而不刪除它
- 4??、enable:使指定的禁用的監(jiān)視點(diǎn)
- 5??驹止、ignore:設(shè)置忽略依靠指定的監(jiān)視點(diǎn)
- 6??浩聋、list:列出所有監(jiān)測(cè)點(diǎn)配置的表
- 7??、modify:在監(jiān)視點(diǎn)或者設(shè)置監(jiān)測(cè)點(diǎn)上修改可執(zhí)行文件臊恋,如果沒(méi)有指定監(jiān)視點(diǎn)衣洁,就傳遞一個(gè)空參數(shù)做修改。
- 8??抖仅、set:設(shè)置監(jiān)視點(diǎn)
例子:
創(chuàng)建一個(gè)監(jiān)視點(diǎn)
watchpoint set expression -- a(這個(gè)a 在代碼中是 int a = 0;)
會(huì)輸出這樣的信息
Watchpoint created: Watchpoint 1: addr = 0x00000000 size = 8 state = enabled type = w
分別為:監(jiān)視點(diǎn)的代號(hào)坊夫,內(nèi)存地址,大小撤卢,狀態(tài)和類型环凿。
再添加個(gè)對(duì)這個(gè) a 的讀寫檢測(cè)
watchpoint set variable -w read_write a
則會(huì)輸出
- 1??、command:添加,刪除和檢查L(zhǎng)LDB命令當(dāng)監(jiān)視點(diǎn)
Watchpoint created: Watchpoint 3: addr = 0x7fff54ed67c4 size = 4 state = enabled type = rw
declare @ '/Users/XXX/Desktop/Demozz/Demozz/ViewController.m:89'
watchpoint spec = 'a'
new value: 0
比上面的輸出相比,多了以下幾點(diǎn)改變
1放吩、監(jiān)視點(diǎn)的代號(hào)智听、內(nèi)存地址、大小渡紫、類型都變了到推。
2、增加了declare(狀態(tài)聲明)
3惕澎、增加了監(jiān)視點(diǎn)的規(guī)范
4莉测、增加了輸出這個(gè)檢查的變量的值。
那我們打印一些監(jiān)視點(diǎn)的列表
watchpoint list
則輸出
Number of supported hardware watchpoints: 4
Current watchpoints:
Watchpoint 1: addr = 0x00000000 size = 8 state = enabled type = w
Watchpoint 3: addr = 0x7fff54ed67c4 size = 4 state = enabled type = rw
declare @ '/Users/miya-shaocong/Desktop/Demozz/Demozz/ViewController.m:89'
watchpoint spec = 'a'
new value: 0
如果我們想刪除一個(gè)監(jiān)視點(diǎn)集灌,只需要把代號(hào)給提交過(guò)去就好了悔雹。
watchpoint delete 1
想刪除全部的話复哆,就這樣
watchpoint delete
它會(huì)讓你確認(rèn)
About to delete all watchpoints, do you want to do that?: [Y/n]
然后你輸入 Y 確定就好了。
- po 顯示任何返回值與控制的格式類型
- 變量
比如你想看某個(gè)變量的值腌零,不需要在代碼中添加log梯找,直接斷點(diǎn)到那個(gè)地方,然后 po 變量名益涧,就會(huì)輸出你想要看到值
- 變量
(lldb) po b
100
- 坐標(biāo)
比如你想看到某個(gè)視圖的坐標(biāo)以及大小信息锈锤,那就直接 po 這個(gè)視圖的frame。
(lldb) po self.view.frame
(origin = (x = 0, y = 0), size = (width = 375, height = 667))
你還可以嘗試輸出其他(你想要看的東西)闲询。
- print 更詳細(xì)的輸出久免,(包括類型)
(lldb) print a
(int) $5 = 0
(lldb) print b
(int) $6 = 100
(lldb) print self.view
(UIView *) $7 = 0x00007fd183d04cf0
(lldb) print self.view.frame
(CGRect) $8 = (origin = (x = 0, y = 0), size = (width = 375, height = 667))
$X 這種是命令結(jié)果的引用名,我們可以用于任何其他表達(dá)式或者接收參數(shù)的命令扭弧。
比如:
(lldb) print $5 + 109
(int) $9 = 109
// ---
(lldb) po $8
(origin = (x = 0, y = 0), size = (width = 375, height = 667))
- next 直接跨過(guò)當(dāng)前的斷點(diǎn)阎姥,跳到下一個(gè)斷點(diǎn)位置,并輸出斷點(diǎn)所在的行數(shù)鸽捻。
- run 重新啟動(dòng)程序呼巴。
- kill 終止當(dāng)前的程序
-
可視化工具操作
第一步:右鍵斷點(diǎn),然后選擇Edit Breakponit
第二步:
第三步:運(yùn)行到斷點(diǎn)看結(jié)果