当程序运行时, 程序会存储它的运行信息在调用栈中. 每当方法被调用, 程序就会在调用栈顶添加新的栈帧, 每个栈帧都包含着传递给方法的参数, 方法的局部变量信息, 方法返回后要跳转到的地址信息.
当程序在断点处停止时, 可以通过调试器检查当前栈帧的状态. 通过帧栈状态可以很好地分析方法的行为以及方法是如何和程序的其它部分交互的.
获取当前栈帧的信息
frame info
通过frame info
指令, 可以获取到当前帧栈对应代码的位置, 包括源文件信息以及行号信息.
(lldb) frame info
frame #0: 0x00000001000034cf Greeter`Greeter.greet(name="Mei", self=0x0000000100205bf0) at Greeter.swift:9:12
复制代码
检查变量信息
frame variable(f v)
通过frame variable
指令. 可以获取当前帧栈上的所有变量信息.
(lldb) frame variable
(String) name = "Anton"
(Greeter.Greeter) self = 0x0000000100502920 {
acquaintances = ([0] = "Anton")
}
复制代码
执行表达式
expression
执行表达式是LLDB的一个强大的功能. 通过这个表达式, 可以改变存储的变量信息, 从而改变程序的运行结果.
(lldb) expression -- acquaintances.insert("Mei")
(lldb) expression -- acquaintances.remove("Anton")
(String?) $R1 = "Anton"
复制代码
frame variable(f v)
与 expression
的比较
frame variable (f v ) |
expression -- (p) |
expression -O -- (po ) |
---|---|---|
不会实际运行代码 | 实际运行了代码 | 实际运行了代码 |
使用LLDB的格式输出 | 使用LLDB的格式输出 | 使用自定义的格式(如Swift的 debugDescription )输出, 如果没有自定义格式, 会使用LLDB的格式输出 |
expression
由于会运行表达式, 可能会给程序带来影响, 如果想要安全快速的调试, 可以使用frame variable
获取线程调用栈(Backtrace)
调用栈展示了当前的方法调用结构. 通过thread backtrace(bt)
, 可以沿着调用栈观察到程序是怎样通过调用方法一步一步变为当前状态的.
(lldb) thread backtrace
* thread #1: tid = 0x1288be3, 0x0000000100001a98 Greeter`Greeter.hasMet(name="Anton", self=0x0000000101200190) -> Bool + 24 at Greeter.swift:5, queue = 'com.apple.main-thread', stop reason = step in
frame #0: 0x0000000100001a98 Greeter`Greeter.hasMet(name="Anton", self=0x0000000101200190) -> Bool + 24 at Greeter.swift:5
* frame #1: 0x0000000100001be4 Greeter`Greeter.greet(name="Anton", self=0x0000000101200190) -> () + 84 at Greeter.swift:9
frame #2: 0x00000001000019eb Greeter`main + 155 at Greeter.swift:20
frame #3: 0x00007fff949d05ad libdyld.dylib`start + 1
frame #4: 0x00007fff949d05ad libdyld.dylib`start + 1
复制代码
可以传入整型参数控制展示的帧栈个数
通过 thread backtrace all
可以获取所有线程的调用栈
获取线程列表
thread list
(lldb) thread list
Process 96461 stopped
* thread #1: tid = 0x1384af1, 0x000000010000111f main`sayHello() -> () + 15 at main.swift:2, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
复制代码