Debug Swift debugging with LLDB
Swift & UI 进阶 20m

用 LLDB 调试 Swift 调试问题

Debug Swift debugging with LLDB

2022年6月6日

在 Apple 官方观看视频

一句话判断

当 LLDB 看不到变量值、符号信息丢失时,这场 Session 教你理解 LLDB 的底层工作机制,以及构建系统需要提供什么信息才能让调试器正常工作。

这场 Session 讲了什么

LLDB 团队的 Adrian 以一个纯 Swift 文字冒险游戏项目为案例,深入讲解了 LLDB 在调试 Swift 代码时的工作原理,以及当调试体验变差时如何诊断和修复问题。

Session 聚焦于那些”高级工作流”带来的调试挑战:集成第三方框架、CI 构建、自定义构建系统、为其他开发者构建工具等场景。核心是理解 LLDB 需要从构建系统获取哪些信息(DWARF 调试信息、模块映射、符号文件),以及这些信息缺失时会发生什么。

值得深挖的点

LLDB 需要的三类关键信息。DWARF 调试信息(变量类型、源码位置映射)、Swift 模块信息(类型定义、协议一致性)、以及符号表(函数名、全局变量名)。任何一类信息的缺失都会导致调试体验降级——从完全看不到变量值到只能看到部分类型信息。

第三方框架集成的影响。当你集成了一个没有调试信息的第三方框架,LLDB 可能无法正确解析跨框架边界的类型。Session 演示了一个场景:集成终端 UI 框架后,之前正常的变量显示突然变成了不透明的原始数据。

CI 构建的调试信息管理。CI 构产出的二进制文件如果没有正确保留 DWARF 信息,崩溃报告将无法符号化。dSYM 文件的管理和存档是持续集成流程中容易被忽视的环节。

Swift 模块稳定性(Module Stability)。Swift 的模块稳定性影响 LLDB 能否正确理解跨模块的类型信息。当使用不兼容的 Swift 版本编译的框架时,类型信息可能无法被 LLDB 解析。

代码片段

# 检查二进制文件是否包含 DWARF 调试信息
dwarfdump --debug-info MyFramework.dylib

# 检查 dSYM 文件中的符号信息
dwarfdump --lookup 0x100001234 MyFramework.dSYM/Contents/Resources/DWARF/MyFramework

# 在 LLDB 中验证模块加载情况
(lldb) image list
# 确认你的框架和调试符号文件都已加载

# 检查 Swift 模块是否可被 LLDB 解析
(lldb) image lookup -t MyType
# 如果找不到类型定义,说明模块信息缺失

# 确保 Xcode 构建设置正确
# Debug Information Format = DWARF with dSYM File
# Strip Debug Symbols During Copy = NO (对调试构建)
# Deployment Postprocessing = NO (对调试构建)

最佳实践

  • 构建用于调试的二进制时,确保 Debug Information Format 设置为 “DWARF with dSYM File”
  • CI 流程中务必存档 dSYM 文件,它们是后续崩溃分析的基础
  • 集成第三方框架时,优先选择提供调试符号的版本
  • 使用 image listimage lookup 命令诊断 LLDB 的模块加载问题
  • 如果变量显示异常,先检查相关的 Swift 模块是否完整加载
  • 构建工具链开发者要确保输出的二进制包含完整的 DWARF 和模块信息

还有什么值得关注

  • 参考 WWDC21 的 “Discover breakpoint improvements” 了解断点相关的新特性
  • Swift 的类型系统复杂度(泛型、协议、条件一致性)给 LLDB 的类型解析带来了独特挑战
  • 自定义构建系统的开发者需要特别关注 DWARF 信息的生成和保留
  • Xcode 的 Build Settings 中有几个影响调试信息质量的关键选项,值得逐一检查
WWDC 2022