iOS 開發(fā)調(diào)試利器 - LLDB命令

請叫我序猿.jpg

lldb的Xcode默認的調(diào)試器,它與LLVM編譯器一起,帶給我們更豐富的流程控制和數(shù)據(jù)檢測的調(diào)試功能。平時用Xcode運行程序,實際走的都是lldb。熟練使用lldb,可以讓你debug事半功倍

  • lldb 用法
    首先在應用程序內(nèi)打斷點。
    接下來一個一個的去介紹和使用。

  • apropos :調(diào)試器命令列表相關的詞或主題
    語法:apropos <search-word>
    作用:輸出你想要搜索的關鍵詞的相關內(nèi)容。
    例子:apropos log
    結(jié)果:

    apropos.png
  • breakpoint :命令操作斷點
    語法:breakpoint <subcommand> [<command-options>]
    作用:可以通過命令來對斷點進行增加、刪除等操作。
    一些子命令如下:
    1、clear:刪除或禁用斷點匹配指定的源文件和行。
    2、command:命令添加,刪除和清單LLDB命令在遇到斷點時執(zhí)行。
    3、delete:刪除指定的斷點(s)。如果沒有斷點指定,刪除它們。
    4、disable:禁用指定斷點(s),而不刪除它們。如果沒有指定,禁用所有斷點。
    5、enable:使指定的禁用斷點(s)。如果沒有斷點指定,使所有的人。
    6、list:列舉一些或所有斷點配置的詳細級別。
    7、modify:修改選項斷點或設置的斷點可執(zhí)行文件。如果沒有指定斷點,作用于最后創(chuàng)建斷點。
    8、name:命令來管理斷點的名字標簽
    9、set:設置一個斷點或設置斷點的可執(zhí)行文件。
    例子:通過 breakpoint 來添加、刪除以及查找斷點。

查看當前斷點列表

  ![查看當前斷點列表.png](http://upload-images.jianshu.io/upload_images/1622166-558a9f2f240b583c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

紅色框框里面表示斷點的行數(shù)??梢钥闯鰜憩F(xiàn)在也就只有2個斷點,一個在73行,一個在80行。
- 添加一個95行的斷點
breakpoint set -f ViewController.m -l 95
-f 后面的是文件名 -l 后面是行數(shù)
- 再次查看當前斷點列表

  ![再次查看斷點列表.png](http://upload-images.jianshu.io/upload_images/1622166-5fe514ad42966a48.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
- 刪除 80 行的斷點
      breakpoint clear -f ViewController.m -l 80
- 結(jié)果列表中就沒有 80 行的斷點信息了。
![最后的斷點列表.png](http://upload-images.jianshu.io/upload_images/1622166-790ba6f138a700a7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  • bugreport :命令來創(chuàng)建特定于域的bug報告
    語法:bugreport <subcommand> [<subcommand-options>]
    作用:創(chuàng)建一份 bug 報告
    例子:
    bug report unwind XXX(XXX 是你想看的方法名)
    結(jié)果會輸出一堆東西。you can try!

  • command :管理自定義命令LLDB命令(創(chuàng)建別名)
    語法:command <subcommand> [<subcommand-options>]
    一些子命令:
    1、alias:定義一個自定義命令
    2、delete:刪除一個或多個自定義命令的命令
    3、history:當前執(zhí)行的歷史命令
    4、regex:定義一個現(xiàn)有命令的自定義命令
    5、script:來管理自定義命令實現(xiàn)的腳本解釋器
    6、source:從文件讀取和執(zhí)行命令LLDB
    7、unalias:刪除一個或多個自定義命令定義為“命令別名”
    例子:
    想知道你執(zhí)行 LLDB 幾條命令,輸入
    command history
    還有個實用的例子:
    比如上面的添加斷點命令過長,那么我們可以這樣做。
    command alias bkt breakpoint set -f %1 -l %2
    然后再添加斷點。
    bkt ViewController.m 90
    你看結(jié)果會發(fā)現(xiàn)已經(jīng)添加上了,是不是很方便?


    別名添加斷點.png

    如果不想要這個別名了就可以執(zhí)行下列命令把它給刪除。
    command unaries but

  • disassemble :拆卸指定的指令
    語法:disassemble [<cmd-options>]
    例子:
    disassemble -b
    這樣會顯示你當前斷點所在的方法內(nèi)所有的操作碼字節(jié)。
    效果:


    操作碼字節(jié).png

    紅色框內(nèi)的信息能更好的幫助你調(diào)試程序。
    如果你想拆卸某一行可以用下面的命令:
    disassemble -c 84(這個數(shù)字就是你想要拆卸的行數(shù),當然了他會聯(lián)系上下文給你拆卸這個對象的信息)

  • expression (我用到的: 修改程序中的代碼)
    場景:假設你程序運行后發(fā)現(xiàn)有個視圖的背景顏色不好看,需要改,好吧,在代碼中改一下,再運行。發(fā)現(xiàn)不好看,再改。這樣太過麻煩,但是我們可以用 expression 來實現(xiàn),代碼:
    expression imageView.backgroundColor = [UIColor redColor]
    然后再運行你就會發(fā)現(xiàn)這個視圖的顏色變成紅色了。不止顏色,一些數(shù)值也是可以改的。

  • frame 命令選擇與當前線程的堆棧幀
    子命令:
    1、info:列表當前堆棧幀在當前的信息線程
    2、select:選擇當前堆??蚣軆?nèi)通過索引當前線程
    3、variable:顯示變量當前堆棧幀。默認為所有參數(shù)和局部變量的范圍
    效果:


    frame效果圖.png

    1中,箭頭表示的是你斷點所在的位置
    后面的就是你所寫的代碼
    2中,有你當前所在的類的名字,所在方法的方法名以及一些創(chuàng)建的對象
    3中,就是列舉方法名,行數(shù),類名等信息。
    根據(jù)自己的喜好選擇相應的命令。

  • quit 退出當前的LLDB。

  • register 訪問當前線程的寄存器和堆棧幀
    子命令:
    1、read:讀取當前的寄存器值當前幀
    2、write:修改一個寄存器值

  • settings 管理 LLDB 的設置
    子命令:
    1、append:將值附加到調(diào)試器里面。數(shù)組、字典或者字符串設置。
    2、clear:清除調(diào)試器
    3、insert-after:在指定的元素的索引,將一個或多個值插入一系列調(diào)試器設置
    4、insert-before:在指定的元素的索引,立刻將一個或多個值插入一系列調(diào)試器設置
    5、list:調(diào)試器列表
    6、remove:移除設置
    7、replace:替換設置中的值
    8、set:設置指定的調(diào)試器的設置值
    9、show:顯示調(diào)試器設置和他們目前的值。

  • source 檢查源代碼所描述的調(diào)試信息當前目標的過程
    子命令:
    1、info:顯示一行信息來源為當前目標的過程。默認為當前堆棧幀中指令指針
    2、list:顯示指定的當前目標過程的源代碼

  • thread 操作在一個或多個線程在當前過程
    子命令:
    1、backtrace:顯示線程調(diào)用堆棧。默認為當前可以指定線程,線程索引作為參數(shù)。使用thread-index看到所有線程。
    2、continue:繼續(xù)執(zhí)行當前目標的過程。
    3、info:顯示一個擴展的總結(jié)一個或多個線程。
    4、jump:將程序計數(shù)器設置為一個新的地址。
    5、list:顯示每個線程在當前目標的總結(jié)的過程。
    6、plan:管理線程控制計劃執(zhí)行。
    7、return:返回從堆棧幀,短路執(zhí)行更新的框架和選擇屈服指定的值。
    8、select:更改當前選中的線程。
    9、step-in:進入調(diào)用
    10、step-init:單步調(diào)用
    11、step-ints-over:單步,跨過調(diào)用。
    12、step-out:執(zhí)行完當前堆棧幀并停止之后返回。
    13、step-over:單步,跨過調(diào)用。
    14、step-scripted:C中選擇的腳本類。
    15、until:到達到行號或地址當前或指定的線程,停止時返回從當前函數(shù)作為一種安全措施。
    例子:
    thread info


    當前線程的信息.png
  • type 命令操作的類型系統(tǒng)
    子命令:

    • 1??、category:操作類型分類
      • define:定義一個新的類別
      • delete:刪除一個類別
      • disable:禁用一個類別
      • enable:啟用一個類別
      • list:現(xiàn)有的類別的列表
    • 2??、filter:操作類型過濾器
      • add:添加一個新的過濾器的類型
      • clear:刪除所有現(xiàn)有的過濾器
      • delete:刪除現(xiàn)有的濾波器類型
      • list:顯示當前過濾器的列表
    • 3??、format:自定義值顯示格式
      • add:添加一個新的格式類型
      • clear:刪除所有現(xiàn)有的格式樣式
      • delete:刪除現(xiàn)有的格式風格類型
      • info:評估提供的表達式和顯示格式應用于結(jié)果值
      • list:顯示當前的列表格式
    • 4??、lookup:當前查找類型和聲明
    • 5??、summary:編輯變量匯總
      • add:添加一個新的匯總的風格類型
      • clear:刪除所有現(xiàn)有的總結(jié)
      • delete:刪除現(xiàn)有的一種總結(jié)類型
      • info:評估提供的表達式和顯示總結(jié)應用結(jié)果值
      • list:顯示當前的列表格式
    • 6??、synthetic:操作合成類型
      • add:添加一個新類型合成提供者
      • clear:刪除所有的類型
      • delete:刪除現(xiàn)有的一種合成類型
      • info:評估提供的表達式和顯示總結(jié)應用結(jié)果值
      • list:顯示當前的列表格式
  • version 顯示調(diào)試器LLDB版本

  • watchpoint 操作檢查點,檢查內(nèi)存的讀寫。

    • 1??、command:添加,刪除和檢查LLDB命令當監(jiān)視點
      • add:添加一組命令LLDB監(jiān)視點
      • delete:刪除監(jiān)視點
      • list:監(jiān)視點成功的列表
    • 2??、delete:刪除指定的監(jiān)視點
    • 3??、disable:禁用指定的監(jiān)視點,而不刪除它
    • 4??、enable:使指定的禁用的監(jiān)視點
    • 5??、ignore:設置忽略依靠指定的監(jiān)視點
    • 6??、list:列出所有監(jiān)測點配置的表
    • 7??、modify:在監(jiān)視點或者設置監(jiān)測點上修改可執(zhí)行文件,如果沒有指定監(jiān)視點,就傳遞一個空參數(shù)做修改。
    • 8??、set:設置監(jiān)視點
      例子:
      創(chuàng)建一個監(jiān)視點
      watchpoint set expression -- a(這個a 在代碼中是 int a = 0;)
      會輸出這樣的信息
      Watchpoint created: Watchpoint 1: addr = 0x00000000 size = 8 state = enabled type = w
      分別為:監(jiān)視點的代號,內(nèi)存地址,大小,狀態(tài)和類型。
      再添加個對這個 a 的讀寫檢測
      watchpoint set variable -w read_write a
      則會輸出
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

比上面的輸出相比,多了以下幾點改變
1、監(jiān)視點的代號、內(nèi)存地址、大小、類型都變了。
2、增加了declare(狀態(tài)聲明)
3、增加了監(jiān)視點的規(guī)范
4、增加了輸出這個檢查的變量的值。
那我們打印一些監(jiā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

如果我們想刪除一個監(jiān)視點,只需要把代號給提交過去就好了。
watchpoint delete 1
想刪除全部的話,就這樣
watchpoint delete
它會讓你確認
About to delete all watchpoints, do you want to do that?: [Y/n]
然后你輸入 Y 確定就好了。

  • po 顯示任何返回值與控制的格式類型
    • 變量
      比如你想看某個變量的值,不需要在代碼中添加log,直接斷點到那個地方,然后 po 變量名,就會輸出你想要看到值
(lldb) po b
100
  • 坐標
    比如你想看到某個視圖的坐標以及大小信息,那就直接 po 這個視圖的frame。
(lldb) po self.view.frame
(origin = (x = 0, y = 0), size = (width = 375, height = 667))

你還可以嘗試輸出其他(你想要看的東西)。

  • print 更詳細的輸出,(包括類型)
(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é)果的引用名,我們可以用于任何其他表達式或者接收參數(shù)的命令。
比如:

(lldb) print $5 + 109
(int) $9 = 109
// ---
(lldb) po $8
(origin = (x = 0, y = 0), size = (width = 375, height = 667))
  • next 直接跨過當前的斷點,跳到下一個斷點位置,并輸出斷點所在的行數(shù)。
  • run 重新啟動程序。
  • kill 終止當前的程序
  • 可視化工具操作
    第一步:右鍵斷點,然后選擇Edit Breakponit
    第二步:


    Xcode可視化工具.png

    第三步:運行到斷點看結(jié)果


    結(jié)果.png

好了,我要分享的關于 LLDB 的命令就到這里了,如果想要學習其他的命令,可以通過 help 來自己學習。如果您覺得這篇文章對你有用,能否給個喜歡?

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

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

  • 前言 LLDB是個開源的內(nèi)置于XCode的具有REPL(read-eval-print-loop)特征的Debug...
    Noskthing閱讀 18,732評論 10 89
  • [轉(zhuǎn)]淺談LLDB調(diào)試器文章來源于:http://www.cocoachina.com/ios/20150126/...
    loveobjc閱讀 2,737評論 2 6
  • 轉(zhuǎn)載 與調(diào)試器共舞 - LLDB 的華爾茲: https://objccn.io/issue-19-2/ 推薦:i...
    F麥子閱讀 3,463評論 0 10
  • 隨著Xcode 5的發(fā)布,LLDB調(diào)試器已經(jīng)取代了GDB,成為了Xcode工程中默認的調(diào)試器。它與LLVM編譯器一...
    隨風飄蕩的小逗逼閱讀 1,464評論 0 0
  • 江歌劉鑫事件,具體內(nèi)容不說了,網(wǎng)絡這么發(fā)達,隨便一百度就有了。就算不百度,公眾號上也都在發(fā)發(fā)發(fā),發(fā)到連我這種不關心...
    李戶勒大閱讀 453評論 0 1

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