LLDB进阶:使用命令行进行检查

LLDB进阶:使用命令行进行检查

LLDB 是一个命令行调试环境,功能类似于 GDB。LLDB 为 Xcode 提供了底层调试环境,在调试区域内设有控制台窗格,方便直接访问 Xcode IDE 环境中的 LLDB 命令

这篇简要介绍 LLDB 的语法和命令特性,介绍命令别名功能的使用,并介绍 LLDB 的帮助系统

关于基础部分可以阅读我之前的博客:《运行,暂停,检查:探索如何使用LLDB进行有效调试》

LLDB命令结构

所有刚开始使用LLDB的用户都应该了解LLDB的命令结构和语法,以便挖掘LLDB的潜力,并了解如何最大化发挥其作用

在许多情况下,LLDB提供的命令与GDB命令类似,这样可以使得有经验的GDB玩家更容易上手LLDB

你知道吗?
GDB (GNU Debugger) 是 Linux 和 Unix 系统下最常用、最强大的程序调试工具。它主要用于调试 C、C++、Go、Rust 等语言编写的程序

简单来说,GDB 就像是给你的程序拍了一张"X光片",允许你在程序运行时查看其内部状态,或者在程序崩溃时"时光倒流"去查看原因

理解LLDB命令语法

LLDB 命令语法始终结构化且规则。LLDB 命令的格式如下:

复制代码
<command> [<subcommand> [<subcommand>...]] <action> [-options [option-value]] [argument [argument...]]

commandsubcommand 是LLDB调试命令,其按照层级结构排列:command 命令为其后subcommand 创建上下文,后者再次为下一层级subcommand创建上下文,依此类推

动作,即action 为你想在这个上下文中执行的操作

选项(options)是动作的修改器,一般是一个值

参数(argument)会根据上下文表示多种不同的内容

这里的上下文可能有些难以理解,实际上把他当作链式调用即可

例如我们要把一个View添加到ViewController 里,我们不能直接add,而是需要一个可以执行该方法的对象即self.view

这里的上下文就是这个意思,实际上这里的意思是想告诉你

LLDB 的命令是不能乱序的,前面的词(Command)决定了后面的词(Subcommand/Action)的具体含义和有效性。 前面的词就是后面的词赖以生存的"环境"

这样写还是有点乱,我们来看一个例子

swift 复制代码
po self.view

还记得这个指令吗?我在第一篇关于LLDB的博客中介绍过,在终端打出这个指令之后,LLDB会以一种相对友好的方式来告诉你这个对象的各种信息

对于这行命令,它实际上是简写形式,我们把他展开来看

swift 复制代码
expression --object-description -- self.view

比较复杂是吧,接下来我们拿着这行命令来对它进行解刨

  1. Command & Subcommand (对象/上下文):

    expression 即为对应部分,这是动作的发起者,你可以把他想象成一个类,它的上下文含义即为:我要开始在这里运行一段代码了

    这样调试器就知道了你后面输入的是代码而不是什么奇奇怪怪的东西

  2. Action (动作):

    这里并没有action的部分,这是因为expression本身只有一个核心功能,在这种情况下,action会被自动并入

  3. Options (选项/修饰符):

    --object-description 这是一个动作修饰符,平常我们缩写为-o

    这行是在配置expression的行为,即打印出人能读懂的东西而不是内存地址,它类似于description 方法

  4. Arguments (参数):

    self.view 这是参数内容

    expression需要一段有效的代码作为参数,所以这里必须是代码

    在这里,参数是一个OC的属性访问语法

LLDB 命令行解析会在命令执行之前完成。命令(command)、子命令(subcommand)、选项(options)、选项值(option-value)、参数(argument)都是用空格分隔的

双引号(" ")用于保护选项值(option-value)和参数(argument)中的空格

如果需要将反斜杠(\)或者双引号(")放入参数(argument)中,则需要在参数中该字符前加上反斜杠(\)。LLDB 等效地使用单引号(')和双引号("),以允许轻松编写命令行中的双引号部分

使用命令选项

像我们刚刚的例子中一样,LLDB 中的命令选项有规范形式和缩写形式。例如,以下是断点集合命令的部分命令选项列表,括号内列出了规范形式:

swift 复制代码
breakpoint set
       -M <method> ( --method <method> )
       -S <selector> ( --selector <selector> )
       -b <function-name> ( --basename <function-name> )
       -f <filename> ( --file <filename> )
       -l <linenum> ( --line <linenum> )
       -n <function-name> ( --name <function-name> )
...

在LLDB中使用命令补全

如果你有在我的第一篇博客中动手实践过,那你应该发现LLDB 支持源文件名、符号名、文件名等的命令补全

在终端窗口中,通过在命令行输入制表符字符来启动完成

Xcode 控制台中的补全功能与源代码编辑器中的补全相同:

完成补全在输入第三个字符后自动弹出,补全弹窗可通过 Esc(Esc)键手动调用。此外,Xcode 控制台中的补全遵循编辑面板中指定的 Xcode 文本编辑偏好设置

命令别名与帮助

现在我们已经了解了LLDB的命名别名机制来构造常用的命令的别名,例如你的代码全是bug,网络请求一运行就报错,所以反复输入

swift 复制代码
(lldb) breakpoint set --file foo.c --line 12

你可以构造一个别名

swift 复制代码
(lldb) command alias bfl breakpoint set -f %1 -l %2

这样你就可以输入命令

swift 复制代码
(lldb) bfl foo.c 12

由于命令别名在各种情况下都很有用,我们应该熟悉它们的结构

你知道吗?

LLDB已经添加了一些alias(例如,step、next、continue),但并未为所有命令添加alias,因为每个命令可以使用一个或两个单独字母表示更为方便,即命令的简写形式更为方便

然而,用户可以根据个人偏好设置LLDB别名。用户配置的别名会保存在~/.lldbinit文件,LLDB启动时会读取该文件。help命令会索引别名以方便查看已设置的别名

要查看所有当前定义的别名及其定义,请使用 help -a 命令,并在帮助输出末尾找到当前定义的别名,从以下开始:

The following is a list of your current command abbreviations (see 'help command alias' for more info):

对于已经命名别名的命令,你可以使用(lldb) command unalias bfl来移除他们

使用快捷键来调试

Debug时,使用快捷键可以提高调试效率,下面是一些常用快捷键:

功能 快捷键 命令
显示、隐藏控制台 Cmd + Shift + Y
启用、禁用所有断点 Cmd + Y breakpoint enablebreakpoint disable
光标移动到控制台 Cmd + Shift + C
清空控制台 Cmd + K
暂停、继续 Cmd + Ctrl + Y continue
step over F6 next
step into F7 step
step out F8 finish

参考资料:

  1. LLDB官方文档
  2. Apple官方文档:开始学习LLDB调试
  3. WWDC2024-10198-运行,暂停,检查:探索如何使用LLDB进行有效调试
相关推荐
z***y8623 小时前
Swift在iOS中的Xcode
ios·xcode·swift
AirDroid_cn3 小时前
iOS 18 后台应用偷跑流量,如何限制?
macos·ios·cocoa
明君879976 小时前
Flutter 图纸标注功能的实现:踩坑与架构设计
android·ios
江东小bug王7 小时前
深入理解 UINavigationController:生命周期、动画优化与性能调优
ios
Lexiaoyao208 小时前
Apple StoreKit 2 开发指南
ios·apple
2501_915106321 天前
iOS App 测试工具全景分析,构建从开发调试到线上监控的多阶段工具链体系
android·测试工具·ios·小程序·uni-app·iphone·webview
Digitally1 天前
如何通过蓝牙将联系人从 iPhone 传输到 Android
android·ios·iphone
90后的晨仔1 天前
2025年11月27日年解决隐私清单导致审核总是提示二进制无效的问题
ios
songgeb1 天前
iOS Audio后台模式下能否执行非Audio逻辑
ios·swift