一、Add BreakPoint
1. 代码中添加断点

2. 根据断点类型添加
-
在 Xcode 的左侧工具栏,点击 BreakPoint Tool,点击左下角的 "+", 添加对应类型的 BreakPoint
-
最常见的就是设置 OC Expection BreakPoint 和 Swift Error BreakPoint


二、 Edit Breakpoint


1. Condition:
为断点设置条件
2. Action:
-
Classify: AppleScript / Capture GPU Frame / Debugger Command / Log Message / Shell Command / Sound
-
Debugger Command 可以添加 LLDB 命令
-
Log Message 可以打印日志
3. Options:
Automatically continue after evaluating actions 执行完后跳过断点
三、Watch Variable
变量值被修改时暂停
1. 搜索过滤变量的名字
2. 右键 Watch "<Valiable>"

四、 代码注入
使用表达式 expression <expr>
1. Edit BreakPoint,添加一个 Debugger Command Action

2. 或者在 lldb 中输入 expression <expression>
如果我们利用 expression 进行一个 UI 的修改,这时屏幕可能未能及时渲染,需要再运行
expression CATransaction.flush()
刷新界面
在 Swift 框架中注入 OC 代码
expression -l obj -O --<expression>
五、代码跳过
1. 使用表达式 thread jump --by 1

2. 移动指针指令的汉堡菜单
可以将指针指令跳转到任意位置,但是这里并不能保证 app 的状态完好无损,有可能会引起内存管理问题, 例如: 试图引用尚未初始化的对象,或者过早释放的对象

六、Symbolic BreakPoint
在调用某个方法的时候触发断点

则在系统调用 -[UILabel setText:]
时会触发断点,通过堆栈我们可以看到是哪些代码调用了该方法
-
在 lldb 中我们可以通过
po $arg1($arg2, etc)
来获取方法的参数值 $arg1 第一个参数 -
如果需要在运行某段代码之后进行方法监听,可以添加一个 BreakPoint,然后 Edit BreakPoint
-
Add Debugger Command Action:
breakpoint set --one-shot true -n [UILabel setText:]
-
这里
--one-shot true
指的是只执行一次,触发后会自动删除
七、LLDB: p / po / v(Xcode10.2)
Shortcut | Expression | Function |
---|---|---|
po <expression> |
expression --object-description --<expr> |
1. Expression: evaluate <expr> 2.Expression: debug Description |
p <expression> |
expression --<expr> |
1. Expression: evaluate <expr> 2.Outputs LLDB-formatted description |
frame variable <name> |
1. Reads value of <name> from memory 2. Outputs LLDB-formatted description |
- po -- Object description / Access to the full lanauage
- p -- Data Formatters / Access to the full lanauage
- v -- Data Formatters / Iterative dynamic type resolution
po 和 p 可以访问当前执行的完整语言,v 有自己的语法
1. po

- 先是生成一段源代码
func __lldb_expr() {
__lldb_res = view
}
-
使用嵌入式的 Swift 编译器来编译代码
-
执行完代码后得到 lldb 需要访问的结果值
-
为了得到对象描述,需要将结果值写入到另外一个的源代码中编译并进行
func __lldb_expr2 -> String() {
return __lldb_res.description
}
- 最终显示 object debug description
2. p

-
第一部分同 po 生成源代码编译并执行
-
动态类型解析结果
-
格式化输出,若未格式化,就和
expression --raw --<expr>
结果一样
动态类型解析
例如 Protocol: Activity / Class: Trip
且 Trip 遵循 Activity 协议
当 let cruise: Activity = Trip()
当我们 p cruise
时,控制台会打印 cruise 作为 Trip 类型的所有描述
由于我们在代码中的静态代码表达,是 Activity 类型,所以当 p cruise.name
时编译时会发生错误
即 p 只对格式化结果进行一次动态类型解析
需要对类型进行格式转换 p (cruise as! Trip).name
才能访问属性
3. v(frame variable)

-
查询在程序中的状态,在内存中定位变量,之后在内存中读取变量值,然后进行动态类型解析,并格式化
-
如果是多个点语法
v variable.field1.field2
,会执行多次动态类型解析,不同于 p,不使用嵌入式编译器,可执行v cruise.name
,通过每次动态解析的类型访问属性
网友评论