Xcode------LLDB Debugger 与断点调试学习
文章目录
- [Xcode------LLDB Debugger 与断点调试学习](#Xcode——LLDB Debugger 与断点调试学习)
-
- 前言
- 介绍
- 打开LLDB
- 命令
- 断点调试
-
- [异常断点------Exception Breakpoint](#异常断点——Exception Breakpoint)
- [标志断点------Symbolic Breakpoint](#标志断点——Symbolic Breakpoint)
- watchpoint
- 断点行为
- condition条件判断
- 最后
- 参考文章
前言
在前几日完成知乎日报项目的过程之中,运行调试是在写项目过程之中最头疼的事情,偶然看到隔壁的倪神在学习与LLDB相关的BUG调试的内容,于是就对LLDB进行学习了解
介绍
LLDB 是 Apple 提供的一个强大且现代化的调试工具,主要用于调试 macOS 和 iOS 应用程序。它是 Xcode 默认的调试器,具有高效、快速的特点,支持多种编程语言,包括 Objective-C、Swift 和 C/C++。LLDB 绑定在 Xcode 内部,存在于主窗口底部的控制台中。调试器允许你在程序运行的特定时暂停它,你可以查看变量的值,执行自定的指令,并且按照你所认为合适的步骤来操作程序的进展。
打开LLDB
在我们平时的编程之中,有些时候也会用到断点去进行调试,相信大家在使用断点时,Xcode总会出现以下界面吧
这个绿色的llbd字样的内容,一直没有引起我的注意,知道学习了lldb才知道这个就是我们进行调试的关键,我们先给出一个简单的程序框架,来开始我们对lldb的学习吧
命令
help
第一个lldb的命令就是help,它可以列出所有的命令,如果你忘记了一个命令的具体作用。你可以使用help + 具体的命令名,例如:help print
这个函数很简单,顾名思义就是打印出变量或者对象,我们在lldb命令框之中写入以下内容
lldb
print c
注:LLDB为了简便操作,其实会实现前缀匹配,所以我们可以使用p,pri,prin来运行print,至于pr会和process命令冲突所以无法使用
这个print会将c的类型等相关信息打印出来,如果说我们打印的是一个数组,那么显示就会变得很复杂,所以我们呢可以用上另一个打印函数po(print object的缩写),这个函数的作用相当于调用了打印对象的description
方法
expression
如果想要改变一个值,或者执行一个方法。可以使用expression
或者e
:
使用expression这个方法,不仅仅改变了调试器之中的值,而且还改变了程序之中的值,此时我们程序的断点之后添加一个NSLog函数去打印a的值,我们可以看到
由于expression
可以改变值,我们可以动态的改变View的颜色,而不需要重新编译:
// 改变颜色
(lldb) expression self.view.backgroundColor = [UIColor redColor]
// 刷新界面
(lldb) expression [CATransaction flush]
不只是改变颜色,frame,animation等都能改变,非常有用。
如最开始所说,不能直接暂停,必须要在当前界面中触发断点,一般来说我们可以通过重写touch方法添加断点等。
断点调试
当我们设置完断点,运行的时候,就会跳出这四个图标:
- continue按钮 =>
continue
,缩写c
- step over按钮 =>
next
,缩写n
- step in按钮 =>
step
,缩写s
- step out按钮 =>
finish
异常断点------Exception Breakpoint
我们平时总是会在写代码的过程之中遇到在main函数之中错误的情况,或许是数组越界或者是监听失败,约束失效,这些错误不能直接确定在其错误的位置,找到错误的内容确实一件很耗时的事情。其实这个也有一个很简单的解决方法,我们可以在编译器的左上角
点击左下角加号
选择Exception Breakpoint,添加之后,要记得右键这个新建的断点,edit breakpoint,将Enable Breakpoint in DisplayViewController.m:191勾选
接下来我们就可以来看看效果了,这里我们监听了一个不存在的属性名字
标志断点------Symbolic Breakpoint
如果我们选择Symbolic Breakpoint,那么就会弹出以下界面,它比普通断点的自定义设置界面多出了两个内容,
Symbol:用来设置当前断点作用域所能识别的方法,这里面既可以是自定义的方法,也可以是系统的API方法。(注意必须表明是类方法还是成员方法)
例如:
objc
-[MyViewController viewDidAppear:]
+[MyViewController sharedInstance]
Module:模组的意思,用来限制满足符号的方法,编译器将只会在断点满足这个模组的符号的时候才回暂停。
watchpoint
一般情况下可以在属性的 set 方法中添加断点,这样就能监控属性的设置。但是有时候,由于不涉及到方法,而是直接操作内存,无法使用断点,但是我们仍要监视某一个值是否变化,这个时候就可以用watchpoin
t来监视。
当指针指向变化时,watchpoint
会触发:
set
添加watchpoint的方式如上图所示
(lldb) watchpoint set variable xxx
断点行为
那在这个我们重写的类之中的KVO监听方法就会发生错误,这里就指出了错误发生的地方,并且产生了一个断点。
上面抛出异常时lldb控制台是没有对应的错误信息输出的。那我们可以在右键编辑断点,点击add action,然后输入po $arg1,因为当我们程序报错的时候,断点一个抛出的参数就是错误信息本身,所以使用这个命令可以输出相关的错误信息
condition条件判断
在循环之中设置断点,似乎是一件很麻烦的事情,我们设置断点之后程序就停在了第一次的循环,有时候我们不需要让代码在每次循环或者被调用的时候停下,我们就可以编辑断点之中的Condition选项。
最后
看NSLog
的文档,第一句话就说:Logs an error message to the Apple System Log facility.
,首先,NSLog
就不是为了普通的debug log进行设计的
,而是error log
;每次NSLog
都会进行很多耗时工作,因此,非重要参数尽量不要用,使用调试之中的print命令进行代替,这也是我们学习lldb的原因所在