日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

LLDB 调试

發(fā)布時(shí)間:2025/6/17 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LLDB 调试 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
LLDB是 XCode 內(nèi)置的為我們開發(fā)者提供的調(diào)試工具。 LLDB 可以提供的服務(wù):
  • 允許你在程序的特定時(shí)刻暫停它;
  • 允許你查看變量的值;
  • 執(zhí)行自定的指令;
  • 按照你所認(rèn)為合適的步驟來操作程序的進(jìn)展。

語(yǔ)法

<command> [<subcommond>] 唯一匹配原則:假如根據(jù)前n個(gè)字母已經(jīng)能唯一匹配到某個(gè)命令,則只寫前n個(gè)字母等效于寫下完整的命令。 每一個(gè) LLDB 命令都包含著 0 個(gè)到多個(gè)子命令,并且可能具有一個(gè)到多個(gè)可選參數(shù)。 --:表示命令(或子命令)的結(jié)束,以及輸入的開始。 express -h +17,讓人很困惑,到底是以 -h 為標(biāo)識(shí),僅僅執(zhí)行 +17,還是計(jì)算 17 和 h 的差值。所以用 -- 表示標(biāo)識(shí)的結(jié)束和輸入的開始。如果想要 -h 作為標(biāo)識(shí),就用 express -h -- +17。如果是要計(jì)算他們的差值,就使用 express -- -h +17。因?yàn)橐话悴皇褂脴?biāo)識(shí)的情況比較多,所以 express -- 就有了一個(gè)簡(jiǎn)寫方式,那就是 print。 輸入 help print 可以看到。 []:表示可選。

常用命令

help

列舉出所有的命令,可以通過 help <command> 來了解更多細(xì)節(jié)。 例如:help thread help print 等。

apropos

有的時(shí)候,可能并不能完全記得某個(gè)命令,只記得某個(gè)關(guān)鍵詞。就可以使用 apropos 搜索到相關(guān)命令信息。 例如:(lldb) apropos stop-hook

print

  • 打印值
根據(jù)唯一匹配原則,你可以使用 prin,pri,甚至 p。但是不能使用 pr,因?yàn)?LLDB 不能消除和 process 的歧義(幸運(yùn)的是 p 并沒有歧義)。
  • 打印對(duì)象
一般打印對(duì)象,會(huì)出現(xiàn) $0 = 0x00007fdb9b71b3e0, 但是我們想看到的是對(duì)象的 description 方法的結(jié)果。 所以使用 -o,告訴 expression 命令以 對(duì)象(object)的方式來打印結(jié)果。 expression -o -- 有個(gè)別名,就是 po (print object)的縮寫。 po [[UIWindow keyWindow] recursiveDescription] 來檢查層次結(jié)構(gòu)。 它可以以文本形式打印出完整的視圖層次結(jié)構(gòu)。 可以用 po [[[UIWindow keyWindow] rootViewController] _printHierarchy] 來檢查視圖控制器。
  • 打印變量
可以給 print 指定不同的打印格式。都是以 print/<fmt> 或者 p/<fmt> 格式書寫。 (lldb) p 16 -> 16 (lldb) p/x 16 //十六進(jìn)制 -> 0x10 (lldb) p/t 16 //二進(jìn)制 -> 0b00000000000000000000000000010000 (lldb) p/t (char)16 ->0b00010000 p/c 打印字符 p/s 打印字符串(以'\0' 結(jié)尾的字符串)

expression

執(zhí)行指定表達(dá)式,并將結(jié)果打印出來。常用于改變調(diào)試器中的值,即改變程序中的值。 完整語(yǔ)法: express <cmd -options> -- <expr> <cmd -options>:命令選項(xiàng),使用默認(rèn)即可; <expr >:要執(zhí)行的表達(dá)式 調(diào)試過程中,我們經(jīng)常用到假設(shè)某個(gè)變量是某個(gè)值,就不需要代碼寫死了;只需打個(gè)斷點(diǎn),執(zhí)行如下即可,非常方便。 例:expr a = 10 在 lldb 中聲明一個(gè)對(duì)象,為了下文中可以使用聲明的變量,變量必須以 美元符開頭。 (lldb) e int $a = 2 (lldb) p $a * 19 -> 38 (lldb) e NAArray *$array = @[@"Sturday", @"Sunday"] (lldb) p [$array count] ->2 (lldb) po [[$array objectAtIndex:0] uppercaseString] -> SATURDAY 注:lldb 無法確定返回的類型

thread backtrace & bt

打印線程堆棧信息 完整語(yǔ)法: thread backtrace [-c <count>] [-s <frame-index>] [-e <boolean>] -c:設(shè)置打印堆棧的幀數(shù) -s:設(shè)置從哪個(gè)幀開始打印 -e:是否顯示額外的回溯 實(shí)際上這些命令選項(xiàng)一般不需要使用。 當(dāng)發(fā)生 crash 時(shí),可以使用 (lldb) thread backtrace //查看棧幀信息 該命令還有一個(gè)別名:bt bt all:打印所有的 thread 堆棧

thread return

thread return [<expr>] 該命令可以接受一個(gè)表達(dá)式,調(diào)用命令后直接從當(dāng)前的 frame 返回表達(dá)式的值。 //它有一個(gè)可選參數(shù),在執(zhí)行時(shí)它會(huì)把可選參數(shù)加載進(jìn)返回寄存器里,然后立刻執(zhí)行返回命令,跳出當(dāng)前棧幀。這意味這函數(shù)剩余的部分不會(huì)被執(zhí)行。這會(huì)給 ARC 的引用計(jì)數(shù)造成一些問題,或者會(huì)使函數(shù)內(nèi)的清理部分失效。但是在函數(shù)的開頭執(zhí)行這個(gè)命令,是個(gè)非常好的隔離這個(gè)函數(shù),偽造返回值的方式 。 thread 還有一些不常用的命令 thread jump:直接讓程序跳到某一行。ARC 下編譯器實(shí)際插入了不少 retain,release命令,跳過一些代碼不執(zhí)行很可能會(huì)造成對(duì)象內(nèi)存混亂發(fā)生 crash。 thread list:列出所有的線程。 thread select:選擇某個(gè)線程。 thread until:傳入一個(gè) line 參數(shù),讓程序執(zhí)行到這行的時(shí)候暫停。 thread info:輸出當(dāng)前線程的信息。

watchpoint

觀察變量或者屬性

這是一個(gè)非常有用的東西,我們經(jīng)常遇到,某一個(gè)變量,不知道什么時(shí)候值被改掉了,就可以使用這個(gè)東西去定位: (lldb) watchpoint set variable self->_string 不能使用點(diǎn)語(yǔ)法

watchpoint set expression (觀察地址)

如果想觀察某個(gè)地址,可以使用 watchpoint set expression 例如:先拿到 _model 的地址,然后對(duì)地址設(shè)置一個(gè) watchpoint (lldb) p &_model (Modek **) $3 = 0x00007fe0dbf23280 (lldb) watchpoint set expression 0x00007fe0dbf23280 Watchpoint created: Watchpoint 1: addr = 0x7fe0dbf23280 size = 8 state = enabled type = w ????new value: 0 watchpoint command 跟 breakpoint 類似,watchpoint 也可以添加命令 watchpoint command add (添加觀察點(diǎn)) 例如: (lldb) watchpoint set variable xxx Watchpoint created: Watchpoint 1: addr = 0x7fe4e1444760 size = 8 state = enabled type = w ????watchpoint spec = '_string' ????new value: 0x0000000000000000 watchpoint 的 id 是1. watchpoint command add -o 'bt' 1 在 watchpoint 停下來時(shí),打印了它的線程信息 也可以添加多條命令: (lldb) watchpoint command add 1 Enter your debugger command(s).??Type 'DONE' to end. > bt > continue > DONE watchpoint command list (某觀察點(diǎn)所有命令) watchpoint command list 1 列出某個(gè) watchpoint 的所有 command watchpoint command delete (觀察點(diǎn)刪除) watchpoint command delete 1 刪除某個(gè) watchpoint 所有的 command watchpoint list (觀察點(diǎn)列表) 查看當(dāng)前所有的 watchpoint,使用 watchpoint list watchpoint disable (觀察點(diǎn)失效) 讓某個(gè) watchpoint 失效 watchpoint enable (觀察點(diǎn)生效) 使某個(gè) watchpoint 生效 watchpoint delete index 刪除某個(gè) watchpoint。 不指定 index,則刪除所有的 watchpoint。

target modules & image:查找地址對(duì)應(yīng)的文件位置

LLDB 給 target modules 取了個(gè)別名 image。 image lookup -address 查找這個(gè)地址具體對(duì)應(yīng)的文件位置。 比如: TLLDB[25086:246169] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 1 beyond bounds for empty NSArray' *** First throw call stack: ( 0?? CoreFoundation??????????????????????0x000000010accde65 __exceptionPreprocess + 165 1?? libobjc.A.dylib???????????????????? 0x000000010a746deb objc_exception_throw + 48 2?? CoreFoundation??????????????????????0x000000010ac7c395 -[__NSArray0 objectAtIndex:] + 101 3?? TLLDB?????????????????????????????? 0x000000010a1c3e36 -[ViewController viewDidLoad] + 86 4?? UIKit?????????????????????????????? 0x000000010b210f98 -[UIViewController loadViewIfRequired] + 1198 5?? UIKit?????????????????????????????? 0x000000010b2112e7 -[UIViewController view] + 27 ) 我們可以看到數(shù)組越界了,但是 objectAtIndex: 的代碼在哪呢? 使用 image lookup (lldb) image lookup -a 0x000000010a1c3e36 ??????Address: TLLDB[0x0000000100000e36] (TLLDB.__TEXT.__text + 246) ??????Summary: TLLDB`-[ViewController viewDidLoad] + 86 at ViewController.m:32 image lookup -name 查找一個(gè)方法 或者 符號(hào)的信息 例如: 第三方 SDK 有一個(gè) Dictionary 的 catagory,和我們自己的 catagory 沖突了,但是不知道在哪個(gè) .a 里面。 使用 image lookup -n dictionaryWithXMLString: 即可。 image lookup -type 查看一個(gè)類型 image lookup -t Model 所有的屬性,實(shí)例變量都會(huì)打出來 target stop-hook 使用 LLDB debug,大多數(shù)時(shí)候需要讓程序 stop。該命令可以在每次 stop 的時(shí)候去執(zhí)行一些命令。 target stop-hook add & display 例如:每次程序 stop 時(shí),都用命令打印當(dāng)前 frame 的所有變量。可以添加一個(gè) stop-hook (lldb) target stop-hook add -o "frame variable" -o:--one-liner,表示添加一條命令。 LLDB 提供了一個(gè)更簡(jiǎn)便的命令:display。下面這兩條等同 (lldb) target stop-hook add -o "p self.view" (lldb) display self.view target stop-hook list 可以查看所有的 stop-hook target stop-hook delete & undisplay 刪除某個(gè) stop-hook (lldb) target stop-hook delete index (lldb) undisplay index target stop-hook disable/enable 使某個(gè) stop-hook 失效/生效。 參考文章 與調(diào)試器共舞 - LLDB 的華爾茲 dSYM詳細(xì)資料 iOS中framework的聯(lián)調(diào)

轉(zhuǎn)載于:https://www.cnblogs.com/lion-witcher/p/10405205.html

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的LLDB 调试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。