LLDB 检查调用栈

语言: CN / TW / HK

当程序运行时, 程序会存储它的运行信息在调用栈中. 每当方法被调用, 程序就会在调用栈顶添加新的栈帧, 每个栈帧都包含着传递给方法的参数, 方法的局部变量信息, 方法返回后要跳转到的地址信息.

当程序在断点处停止时, 可以通过调试器检查当前栈帧的状态. 通过帧栈状态可以很好地分析方法的行为以及方法是如何和程序的其它部分交互的.

获取当前栈帧的信息

frame info

通过frame info 指令, 可以获取到当前帧栈对应代码的位置, 包括源文件信息以及行号信息.

other (lldb) frame info frame #0: 0x00000001000034cf Greeter`Greeter.greet(name="Mei", self=0x0000000100205bf0) at Greeter.swift:9:12

检查变量信息

frame variable(f v)

通过frame variable 指令. 可以获取当前帧栈上的所有变量信息.

other (lldb) frame variable (String) name = "Anton" (Greeter.Greeter) self = 0x0000000100502920 { acquaintances = ([0] = "Anton") }

执行表达式

expression

执行表达式是LLDB的一个强大的功能. 通过这个表达式, 可以改变存储的变量信息, 从而改变程序的运行结果.

other (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) , 可以沿着调用栈观察到程序是怎样通过调用方法一步一步变为当前状态的.

other (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

other (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

参考资料: Examining the Call Stack