美文网首页
iOS - Advanced Debugging with Xc

iOS - Advanced Debugging with Xc

作者: ienos | 来源:发表于2020-12-01 17:18 被阅读0次

一、Add BreakPoint

1. 代码中添加断点
image.gif
2. 根据断点类型添加
  • 在 Xcode 的左侧工具栏,点击 BreakPoint Tool,点击左下角的 "+", 添加对应类型的 BreakPoint

  • 最常见的就是设置 OC Expection BreakPoint 和 Swift Error BreakPoint

image.png image.png

二、 Edit Breakpoint

image.png image.png
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>"
image.png

四、 代码注入

使用表达式 expression <expr>


1. Edit BreakPoint,添加一个 Debugger Command Action
image.png
2. 或者在 lldb 中输入 expression <expression>

如果我们利用 expression 进行一个 UI 的修改,这时屏幕可能未能及时渲染,需要再运行 expression CATransaction.flush() 刷新界面

在 Swift 框架中注入 OC 代码 expression -l obj -O --<expression>

五、代码跳过

1. 使用表达式 thread jump --by 1
image.png
2. 移动指针指令的汉堡菜单

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

image.gif

六、Symbolic BreakPoint

在调用某个方法的时候触发断点


image.png

则在系统调用 -[UILabel setText:] 时会触发断点,通过堆栈我们可以看到是哪些代码调用了该方法

  1. 在 lldb 中我们可以通过 po $arg1($arg2, etc)来获取方法的参数值 $arg1 第一个参数

  2. 如果需要在运行某段代码之后进行方法监听,可以添加一个 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
image.png
  • 先是生成一段源代码
func __lldb_expr() {

    __lldb_res = view

}
  • 使用嵌入式的 Swift 编译器来编译代码

  • 执行完代码后得到 lldb 需要访问的结果值

  • 为了得到对象描述,需要将结果值写入到另外一个的源代码中编译并进行

func __lldb_expr2 -> String() {

    return __lldb_res.description

}
  • 最终显示 object debug description
2. p
image.png
  • 第一部分同 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)
image.png
  • 查询在程序中的状态,在内存中定位变量,之后在内存中读取变量值,然后进行动态类型解析,并格式化

  • 如果是多个点语法 v variable.field1.field2,会执行多次动态类型解析,不同于 p,不使用嵌入式编译器,可执行 v cruise.name,通过每次动态解析的类型访问属性

相关文章

网友评论

      本文标题:iOS - Advanced Debugging with Xc

      本文链接:https://www.haomeiwen.com/subject/vhbswktx.html