iOS常用调试方法:LLDB命令

栏目: IOS · 发布时间: 5年前

内容简介:在iOS项目开发过程中,常用到静态分析(Analyze)、断点(BreakPoint)和控制台(Console)进行代码调试。本篇文章介绍Xcode常用调试方法之”LLDB命令“。本文来自360奇舞团QiShare团队投稿。

在iOS项目开发过程中,常用到静态分析(Analyze)、断点(BreakPoint)和控制台(Console)进行代码调试。本篇文章介绍Xcode常用调试方法之”LLDB命令“。

本文来自360奇舞团QiShare团队投稿。

iOS常用调试方法:LLDB命令

相关阅读:

简介

LLDB是新一代高性能调试器。它构建为一组可重用的组件,可以高度利用较大的LLVM项目中的现有库,例如Clang表达式解析器和LLVM反汇编程序。

LLDB是Mac OS X上Xcode的默认调试器,支持在桌面和iOS设备和模拟器上调试C,Objective-C和C ++。

LLDB项目中的所有代码都是在标准LLVM许可证下提供的,这是一种开源的“BSD风格”许可证。

帮助

LLDB命令格式如下:

<命令名称> <命令动作> [-可选项 [可选项的值]] [参数1 [参数2...]] 

LLDB命令的各部分由空格分割,如果参数中包含空格,则需要使用双引号括起参数,如果参数中包含双引号或者反斜杠,则需要使用反斜杠进行转义。

LLDB命令有非常多的功能,完全背下来不太容易,也没必要。开发者可以使用help命令查看相关命令的用法,甚至可以查看help命令的用法。

(lldb) help help 
     Show a list of all debugger commands, or give details about a specific 
     command. 
 
Syntax: help [<cmd-name>] 
 
Command Options Usage: 
  help [-ahu] [<cmd-name> [<cmd-name> [...]]] 
 
       -a ( --hide-aliases ) 
            Hide aliases in the command list. 
 
       -h ( --show-hidden-commands ) 
            Include commands prefixed with an underscore. 
 
       -u ( --hide-user-commands ) 
            Hide user-defined commands from the list. 
      
     This command takes options and free-form arguments.  If your arguments 
     resemble option specifiers (i.e., they start with a - or --), you must use 
     ' -- ' between the end of the command options and the beginning of the 
     arguments. 

3. 执行

在LLDB中,执行命令expression是最基础的命令,简写为expr或者e,语法为:expression -- ,它的作用是执行一个表达式,并输出表达式返回的结果。示例如下:

iOS常用调试方法:LLDB命令

//! 输出count的值 
(lldb) expression count 
(NSUInteger) $0 = 10 
 
//! 执行string的拼接字符串方法 
(lldb) expression [string stringByAppendingString:@"732"] 
(__NSCFString *) $1 = 0x00006000006ac870 @"QiShare732" 
 
//! 修改view的颜色 
(lldb) expression self.view.backgroundColor = [UIColor redColor] 
(UICachedDeviceRGBColor *) $2 = 0x0000600001d74780 
(lldb) expression [CATransaction flush] 
//!< 因为断点会终止UI线程,执行[CATransaction flush]命令可以渲染出修改后的界面 

4. 打印

打印命令print是最常用的命令,简写为pri或者p,语法为:print ,它的作用是打印变量或者表达式。通过help print会发现print其实是expression --命令的简写:'print' is an abbreviation for 'expression --',其中--标识选项的结束和参数的开始。

同样常用的expression简写命令还有po和call。其中po表示print object,用来打印对象,call用来调用某个方法。示例如下:

iOS常用调试方法:LLDB命令

(lldb) expression -- self.view 
(UIView *) $4 = 0x00007f8ca8401690 
 
(lldb) e self.view 
(UIView *) $5 = 0x00007f8ca8401690 
 
(lldb) p self.view 
(UIView *) $6 = 0x00007f8ca8401690 
 
(lldb) po self.view 
<UIView: 0x7f8ca8401690; frame = (0 0; 375 812); autoresize = W+H; layer = <CALayer: 0x6000008a1dc0>> 
 
(lldb) call self.view 
(UIView *) $8 = 0x00007f8ca8401690 

另外,开发者可以按照print/ 的语法为print命令指定打印格式:

p/x  //!< 以十六进制打印整数 
p/d  //!< 以带符号的十进制打印整数 
p/u  //!< 以无符号的十进制打印整数 
p/o  //!< 以八进制打印整数 
p/t  //!< 以二进制打印整数 
p/a  //!< 以十六进制打印地址 
p/c  //!< 打印字符常量 
p/f  //!< 打印浮点数 
p/s  //!< 打印字符串 
p/r  //!< 格式化打印 

p/x //!< 以十六进制打印整数p/d //!< 以带符号的十进制打印整数p/u //!< 以无符号的十进制打印整数p/o //!< 以八进制打印整数p/t //!< 以二进制打印整数p/a //!< 以十六进制打印地址p/c //!< 打印字符常量p/f //!< 打印浮点数p/s //!< 打印字符串p/r //!< 格式化打印

示例如下:

iOS常用调试方法:LLDB命令

(lldb) p count 
(NSUInteger) $0 = 10 
 
(lldb) p/t count 
(NSUInteger) $1 = 0b0000000000000000000000000000000000000000000000000000000000001010 
 
(lldb) p/o count 
(NSUInteger) $2 = 012 
 
(lldb) p/x count 
(NSUInteger) $3 = 0x000000000000000a 
 
(lldb) p/x string 
(__NSCFConstantString *) $4 = 0x000000010416a0b8 @"QiShare" 
 
(lldb) p/c string 
(__NSCFConstantString *) $5 = \xb8\xa0\x16\x04\x01\0\0\0 @"QiShare" 
 
(lldb) p/s string 
(__NSCFConstantString *) $6 = @"QiShare" 
 
(lldb) p/a string 
(__NSCFConstantString *) $7 = 0x000000010416a0b8 @"QiShare" @"QiShare" 

5. 线程

thread是线程相关的命令,语法为thread [ ],它可以接受不同的可选参数,以实现丰富的功能。其中thread list、thread backtrace和thread return较为常用。

开发者可以使用thread list命令查看当前的所有线程,示例如下:

(lldb) thread list 
Process 4031 stopped 
* 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 
  thread #2: tid = 0x25d2f, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  thread #3: tid = 0x25d30, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  thread #4: tid = 0x25d31, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  thread #5: tid = 0x25d32, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  thread #6: tid = 0x25d33, 0x00000001079ff28a libsystem_kernel.dylib`__workq_kernreturn + 10 
  thread #7: tid = 0x25d3e, 0x00000001079f520a libsystem_kernel.dylib`mach_msg_trap + 10, name = 'com.apple.uikit.eventfetch-thread' 

thread backtrace命令可以方便地供开发者查看线程堆栈信息,简写为bt。比如,当程序崩溃的时候,开发者可以查看堆栈调用列表。示例如下:

iOS常用调试方法:LLDB命令

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

在调试过程中,开发者可以使用thread return命令终端某个方法并返回一个想要的值。示例如下:

iOS常用调试方法:LLDB命令

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

6. 断点

作者在iOS 调试方法:断点这篇文章中介绍过断点的用法。其实,可视化的断点都可以使用LLDB语法来实现。比如下图中的1、2、3、4、5都能用LLDB命令表达。

iOS常用调试方法:LLDB命令

  • 启用/禁用断点(breakpoint enable/disable)
  • 继续执行程序(continue)
  • 执行下一步(next)
  • 进入方法(step)
  • 跳出方法(finish)

在断点相关操作中,因为Xcode已经集成了可视化的断点操作工具,所以breakpoint命令并不被常用。但是,breakpoint命令拥有着十分强大的功能,语法为:breakpoint [ ],主要命令示例如下:

//! 查看所有断点 
(lldb) breakpoint list 
 
//! 为所有类中的viewDidAppear:设置断点 
(lldb) breakpoint set -n viewDidAppear: 
 
//! 为QiConsoleViewController.m文件中的testLLDBCommands方法设定断点 
(lldb) breakpoint set -f QiConsoleViewController.m -n testLLDBCommands 
 
//! 为QiConsoleViewController.m文件中的第32行代码设定断点 
(lldb) breakpoint set -f QiConsoleViewController.m -l 32 
 
//! 为handleString:方法设定条件断点,条件为string != nil 
(lldb) breakpoint set - handleString: -c string != nil 

7. 观察点

想比较于breakpoint是对方法生效的断点,watchpoint则是对地址生效的断点。watchpoint类似于KVO的工作原理,当观察到属性地址里面的东西改变时,就让程序中断,其语法为:watchpoint [ ]。其应用场景示例如下:

iOS常用调试方法:LLDB命令

(lldb) watchpoint set variable string 
Watchpoint created: Watchpoint 1: addr = 0x7ffeef497360 size = 8 state = enabled type = w 
    declare @ '/Users/huangxianshuai/Desktop/Products/QiShare/QiDebugDemo/QiDebugDemo/QiConsoleViewController.m:33' 
    watchpoint spec = 'string' 
    new value: 0x00000001007670b8 
 
(lldb) next 
 
Watchpoint 1 hit: 
old value: 0x00000001007670b8 
new value: 0x0000000100767138 
 
(lldb) image lookup -a 0x00000001007670b8 
      Address: QiDebugDemo[0x00000001000040b8] (QiDebugDemo.__DATA.__cfstring + 32) 
      Summary: @"QiShare" 
(lldb) image lookup -a 0x0000000100767138 
      Address: QiDebugDemo[0x0000000100004138] (QiDebugDemo.__DATA.__cfstring + 160) 
      Summary: @"huang" 

image lookup -a 是 image lookup -address 的简写,可以查看参数地址的内容。

8. 总结

文章仅列举了作者平常使用到的一些LLDB命令,这些命令的确能提高调试效率。而更多的LLDB命令可以从LLDB Homepage( http://lldb.llvm.org /)或者其他网络资源中获取。

【本文是51CTO专栏机构360技术的原创文章,微信公众号“360技术( id: qihoo_tech)”】

iOS常用调试方法:LLDB命令

戳这里,看该作者更多好文


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Book of CSS3

The Book of CSS3

Peter Gasston / No Starch Press / 2011-5-13 / USD 34.95

CSS3 is the technology behind most of the eye-catching visuals on the Web today, but the official documentation can be dry and hard to follow. Luckily, The Book of CSS3 distills the heady technical la......一起来看看 《The Book of CSS3》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具