av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

iOS常用調(diào)試方法:LLDB命令

在iOS項(xiàng)目開發(fā)過(guò)程中,常用到靜態(tài)分析(Analyze)、斷點(diǎn)(BreakPoint)和控制臺(tái)(Console)進(jìn)行代碼調(diào)試。本篇文章介紹Xcode常用調(diào)試方法之”LLDB命令“。

成都創(chuàng)新互聯(lián)自2013年起,公司以成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè)、系統(tǒng)開發(fā)、網(wǎng)絡(luò)推廣、文化傳媒、企業(yè)宣傳、平面廣告設(shè)計(jì)等為主要業(yè)務(wù),適用行業(yè)近百種。服務(wù)企業(yè)客戶近千家,涉及國(guó)內(nèi)多個(gè)省份客戶。擁有多年網(wǎng)站建設(shè)開發(fā)經(jīng)驗(yàn)。為企業(yè)提供專業(yè)的網(wǎng)站建設(shè)、創(chuàng)意設(shè)計(jì)、宣傳推廣等服務(wù)。 通過(guò)專業(yè)的設(shè)計(jì)、獨(dú)特的風(fēng)格,為不同客戶提供各種風(fēng)格的特色服務(wù)。

本文來(lái)自360奇舞團(tuán)QiShare團(tuán)隊(duì)投稿。

相關(guān)閱讀:

  • 《iOS 常用調(diào)試方法:靜態(tài)分析》
  • 《iOS 常用調(diào)試方法:斷點(diǎn)調(diào)試》

1.簡(jiǎn)介

LLDB是新一代高性能調(diào)試器。它構(gòu)建為一組可重用的組件,可以高度利用較大的LLVM項(xiàng)目中的現(xiàn)有庫(kù),例如Clang表達(dá)式解析器和LLVM反匯編程序。

LLDB是Mac OS X上Xcode的默認(rèn)調(diào)試器,支持在桌面和iOS設(shè)備和模擬器上調(diào)試C,Objective-C和C ++。

LLDB項(xiàng)目中的所有代碼都是在標(biāo)準(zhǔn)LLVM許可證下提供的,這是一種開源的“BSD風(fēng)格”許可證。

2.幫助

LLDB命令格式如下:

 
 
 
 
  1. <命令名稱> <命令動(dòng)作> [-可選項(xiàng) [可選項(xiàng)的值]] [參數(shù)1 [參數(shù)2...]] 

LLDB命令的各部分由空格分割,如果參數(shù)中包含空格,則需要使用雙引號(hào)括起參數(shù),如果參數(shù)中包含雙引號(hào)或者反斜杠,則需要使用反斜杠進(jìn)行轉(zhuǎn)義。

LLDB命令有非常多的功能,完全背下來(lái)不太容易,也沒必要。開發(fā)者可以使用help命令查看相關(guān)命令的用法,甚至可以查看help命令的用法。

 
 
 
 
  1. (lldb) help help 
  2.      Show a list of all debugger commands, or give details about a specific 
  3.      command. 
  4.  
  5. Syntax: help [
  6.  
  7. Command Options Usage: 
  8.   help [-ahu] [ [ [...]]] 
  9.  
  10.        -a ( --hide-aliases ) 
  11.             Hide aliases in the command list. 
  12.  
  13.        -h ( --show-hidden-commands ) 
  14.             Include commands prefixed with an underscore. 
  15.  
  16.        -u ( --hide-user-commands ) 
  17.             Hide user-defined commands from the list. 
  18.       
  19.      This command takes options and free-form arguments.  If your arguments 
  20.      resemble option specifiers (i.e., they start with a - or --), you must use 
  21.      ' -- ' between the end of the command options and the beginning of the 
  22.      arguments. 

3. 執(zhí)行

在LLDB中,執(zhí)行命令expression是最基礎(chǔ)的命令,簡(jiǎn)寫為expr或者e,語(yǔ)法為:expression -- ,它的作用是執(zhí)行一個(gè)表達(dá)式,并輸出表達(dá)式返回的結(jié)果。示例如下:

 
 
 
 
  1. //! 輸出count的值 
  2. (lldb) expression count 
  3. (NSUInteger) $0 = 10 
  4.  
  5. //! 執(zhí)行string的拼接字符串方法 
  6. (lldb) expression [string stringByAppendingString:@"732"] 
  7. (__NSCFString *) $1 = 0x00006000006ac870 @"QiShare732" 
  8.  
  9. //! 修改view的顏色 
  10. (lldb) expression self.view.backgroundColor = [UIColor redColor] 
  11. (UICachedDeviceRGBColor *) $2 = 0x0000600001d74780 
  12. (lldb) expression [CATransaction flush] 
  13. //!< 因?yàn)閿帱c(diǎn)會(huì)終止UI線程,執(zhí)行[CATransaction flush]命令可以渲染出修改后的界面 

4. 打印

打印命令print是最常用的命令,簡(jiǎn)寫為pri或者p,語(yǔ)法為:print ,它的作用是打印變量或者表達(dá)式。通過(guò)help print會(huì)發(fā)現(xiàn)print其實(shí)是expression --命令的簡(jiǎn)寫:'print' is an abbreviation for 'expression --',其中--標(biāo)識(shí)選項(xiàng)的結(jié)束和參數(shù)的開始。

同樣常用的expression簡(jiǎn)寫命令還有po和call。其中po表示print object,用來(lái)打印對(duì)象,call用來(lái)調(diào)用某個(gè)方法。示例如下:

 
 
 
 
  1. (lldb) expression -- self.view 
  2. (UIView *) $4 = 0x00007f8ca8401690 
  3.  
  4. (lldb) e self.view 
  5. (UIView *) $5 = 0x00007f8ca8401690 
  6.  
  7. (lldb) p self.view 
  8. (UIView *) $6 = 0x00007f8ca8401690 
  9.  
  10. (lldb) po self.view 
  11.  
  12. (lldb) call self.view 
  13. (UIView *) $8 = 0x00007f8ca8401690 

另外,開發(fā)者可以按照print/ 的語(yǔ)法為print命令指定打印格式:

 
 
 
 
  1. p/x  //!< 以十六進(jìn)制打印整數(shù) 
  2. p/d  //!< 以帶符號(hào)的十進(jìn)制打印整數(shù) 
  3. p/u  //!< 以無(wú)符號(hào)的十進(jìn)制打印整數(shù) 
  4. p/o  //!< 以八進(jìn)制打印整數(shù) 
  5. p/t  //!< 以二進(jìn)制打印整數(shù) 
  6. p/a  //!< 以十六進(jìn)制打印地址 
  7. p/c  //!< 打印字符常量 
  8. p/f  //!< 打印浮點(diǎn)數(shù) 
  9. p/s  //!< 打印字符串 
  10. p/r  //!< 格式化打印 

p/x //!< 以十六進(jìn)制打印整數(shù)p/d //!< 以帶符號(hào)的十進(jìn)制打印整數(shù)p/u //!< 以無(wú)符號(hào)的十進(jìn)制打印整數(shù)p/o //!< 以八進(jìn)制打印整數(shù)p/t //!< 以二進(jìn)制打印整數(shù)p/a //!< 以十六進(jìn)制打印地址p/c //!< 打印字符常量p/f //!< 打印浮點(diǎn)數(shù)p/s //!< 打印字符串p/r //!< 格式化打印

示例如下:

 
 
 
 
  1. (lldb) p count 
  2. (NSUInteger) $0 = 10 
  3.  
  4. (lldb) p/t count 
  5. (NSUInteger) $1 = 0b0000000000000000000000000000000000000000000000000000000000001010 
  6.  
  7. (lldb) p/o count 
  8. (NSUInteger) $2 = 012 
  9.  
  10. (lldb) p/x count 
  11. (NSUInteger) $3 = 0x000000000000000a 
  12.  
  13. (lldb) p/x string 
  14. (__NSCFConstantString *) $4 = 0x000000010416a0b8 @"QiShare" 
  15.  
  16. (lldb) p/c string 
  17. (__NSCFConstantString *) $5 = \xb8\xa0\x16\x04\x01\0\0\0 @"QiShare" 
  18.  
  19. (lldb) p/s string 
  20. (__NSCFConstantString *) $6 = @"QiShare" 
  21.  
  22. (lldb) p/a string 
  23. (__NSCFConstantString *) $7 = 0x000000010416a0b8 @"QiShare" @"QiShare" 

5. 線程

thread是線程相關(guān)的命令,語(yǔ)法為thread [ ],它可以接受不同的可選參數(shù),以實(shí)現(xiàn)豐富的功能。其中thread list、thread backtrace和thread return較為常用。

開發(fā)者可以使用thread list命令查看當(dāng)前的所有線程,示例如下:

 
 
 
 
  1. (lldb) thread list 
  2. Process 4031 stopped 
  3. * thread #1: tid = 0x25cac, 0x0000000104167e23 QiDebugDemo`-[QiConsoleViewController testLLDBCommands](self=0x00007f850df0bbf0, _cmd="testLLDBCommands") at QiConsoleViewController.m:34, queue = 'com.apple.main-thread', stop reason = breakpoint 4.1 
  4.   thread #2: tid = 0x25d2f, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  5.   thread #3: tid = 0x25d30, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  6.   thread #4: tid = 0x25d31, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  7.   thread #5: tid = 0x25d32, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  8.   thread #6: tid = 0x25d33, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  9.   thread #7: tid = 0x25d3e, 0x00000001079f520a libsystem_kernel.dylib`mach_msg_trap + 10, name = 'com.apple.uikit.eventfetch-thread' 

thread backtrace命令可以方便地供開發(fā)者查看線程堆棧信息,簡(jiǎn)寫為bt。比如,當(dāng)程序崩潰的時(shí)候,開發(fā)者可以查看堆棧調(diào)用列表。示例如下:

 
 
 
 
  1. (lldb) thread backtrace 
  2. * thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 
  3.     frame #0: 0x0000000104cc2705 libobjc.A.dylib`objc_exception_throw 
  4.     frame #1: 0x00000001056704ec CoreFoundation`_CFThrowFormattedException + 194 
  5.     frame #2: 0x00000001057a6b00 CoreFoundation`-[__NSArrayI objectAtIndexedSubscript:] + 96 
  6.   * frame #3: 0x00000001043a1df7 QiDebugDemo`-[QiConsoleViewController testLLDBCommands](self=0x00007fadc7c50400, _cmd="testLLDBCommands") at QiConsoleViewController.m:33 
  7.     frame #4: 0x00000001043a1d5a QiDebugDemo`-[QiConsoleViewController viewDidLoad](self=0x00007fadc7c50400, _cmd="viewDidLoad") at QiConsoleViewController.m:26 
  8. ... 
  9.     frame #18: 0x00000001056830be CoreFoundation`__CFRunLoopDoObservers + 430 
  10.     frame #19: 0x0000000105683751 CoreFoundation`__CFRunLoopRun + 1537 
  11.     frame #20: 0x0000000105682e11 CoreFoundation`CFRunLoopRunSpecific + 625 
  12.     frame #21: 0x000000010ddd51dd GraphicsServices`GSEventRunModal + 62 
  13.     frame #22: 0x000000010a1db81d UIKitCore`UIApplicationMain + 140 
  14.     frame #23: 0x00000001043a2450 QiDebugDemo`main(argc=1, argv=0x00007ffeeb85df90) at main.m:7 
  15.     frame #24: 0x0000000107858575 libdyld.dylib`start + 1 

在調(diào)試過(guò)程中,開發(fā)者可以使用thread return命令終端某個(gè)方法并返回一個(gè)想要的值。示例如下:

 
 
 
 
  1. (lldb) thread return string 
  2. (lldb) continue 
  3. 2019-02-27 17:22:47.323225+0800 QiDebugDemo[5071:222700] resultString: Qi_Share 

6. 斷點(diǎn)

作者在iOS 調(diào)試方法:斷點(diǎn)這篇文章中介紹過(guò)斷點(diǎn)的用法。其實(shí),可視化的斷點(diǎn)都可以使用LLDB語(yǔ)法來(lái)實(shí)現(xiàn)。比如下圖中的1、2、3、4、5都能用LLDB命令表達(dá)。

  • 啟用/禁用斷點(diǎn)(breakpoint enable/disable)
  • 繼續(xù)執(zhí)行程序(continue)
  • 執(zhí)行下一步(next)
  • 進(jìn)入方法(step)
  • 跳出方法(finish)

在斷點(diǎn)相關(guān)操作中,因?yàn)閄code已經(jīng)集成了可視化的斷點(diǎn)操作工具,所以breakpoint命令并不被常用。但是,breakpoint命令擁有著十分強(qiáng)大的功能,語(yǔ)法為:breakpoint [ ],主要命令示例如下:

 
 
 
 
  1. //! 查看所有斷點(diǎn) 
  2. (lldb) breakpoint list 
  3.  
  4. //! 為所有類中的viewDidAppear:設(shè)置斷點(diǎn) 
  5. (lldb) breakpoint set -n viewDidAppear: 
  6.  
  7. //! 為QiConsoleViewController.m文件中的testLLDBCommands方法設(shè)定斷點(diǎn) 
  8. (lldb) breakpoint set -f QiConsoleViewController.m -n testLLDBCommands 
  9.  
  10. //! 為QiConsoleViewController.m文件中的第32行代碼設(shè)定斷點(diǎn) 
  11. (lldb) breakpoint set -f QiConsoleViewController.m -l 32 
  12.  
  13. //! 為handleString:方法設(shè)定條件斷點(diǎn),條件為string != nil 
  14. (lldb) breakpoint set - handleString: -c string != nil 

7. 觀察點(diǎn)

想比較于breakpoint是對(duì)方法生效的斷點(diǎn),watchpoint則是對(duì)地址生效的斷點(diǎn)。watchpoint類似于KVO的工作原理,當(dāng)觀察到屬性地址里面的東西改變時(shí),就讓程序中斷,其語(yǔ)法為:watchpoint [ ]。其應(yīng)用場(chǎng)景示例如下:

 
 
 
 
  1. (lldb) watchpoint set variable string 
  2. Watchpoint created: Watchpoint 1: addr = 0x7ffeef497360 size = 8 state = enabled type = w 
  3.     declare @ '/Users/huangxianshuai/Desktop/Products/QiShare/QiDebugDemo/QiDebugDemo/QiConsoleViewController.m:33' 
  4.     watchpoint spec = 'string' 
  5.     new value: 0x00000001007670b8 
  6.  
  7. (lldb) next 
  8.  
  9. Watchpoint 1 hit: 
  10. old value: 0x00000001007670b8 
  11. new value: 0x0000000100767138 
  12.  
  13. (lldb) image lookup -a 0x00000001007670b8 
  14.       Address: QiDebugDemo[0x00000001000040b8] (QiDebugDemo.__DATA.__cfstring + 32) 
  15.       Summary: @"QiShare" 
  16. (lldb) image lookup -a 0x0000000100767138 
  17.       Address: QiDebugDemo[0x0000000100004138] (QiDebugDemo.__DATA.__cfstring + 160) 
  18.       Summary: @"huang" 

image lookup -a 是 image lookup -address 的簡(jiǎn)寫,可以查看參數(shù)地址的內(nèi)容。

8. 總結(jié)

文章僅列舉了作者平常使用到的一些LLDB命令,這些命令的確能提高調(diào)試效率。而更多的LLDB命令可以從LLDB Homepage(http://lldb.llvm.org/)或者其他網(wǎng)絡(luò)資源中獲取。

【本文是專欄機(jī)構(gòu)360技術(shù)的原創(chuàng)文章,微信公眾號(hào)“360技術(shù)( id: qihoo_tech)”】


分享標(biāo)題:iOS常用調(diào)試方法:LLDB命令
轉(zhuǎn)載源于:http://uogjgqi.cn/article/cdgpgjh.html

掃二維碼與項(xiàng)目經(jīng)理溝通

我們?cè)谖⑿派?4小時(shí)期待你的聲音

解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流