发布网友 发布时间:2022-04-08 22:28
共4个回答
懂视网 时间:2022-04-09 02:49
在使用LLDB前,我们需要了解一下LLDB的命令结构及语法,这样可以尽可能地挖掘LLDB的潜能,以帮助我们更充分地利用它。
LLDB命令的语法有其通用结构,通常是以下形式的:
<command></command> [<subcommand> [<subcommand>...]] <action> [-options [option-value]] [argument [argument...]]</action></subcommand></subcommand>
其中:
(命令)和(子命令):LLDB调试命令的名称。命令和子命令按层级结构来排列:一个命令对象为跟随其的子命令对象创建一个上下文,子命令又为其子命令创建一个上下文,依此类推。
:我们想在前面的命令序列的上下文中执行的一些操作。
:行为修改器(action modifiers)。通常带有一些值。
:根据使用的命令的上下文来表示各种不同的东西。
LLBD命令行的解析操作在执行命令之前完成。上面的这些元素之间通过空格来分割,如果某一元素自身含有空格,则可以使用双引用。而如果元素中又包含双引号,则可以使用反斜杠;或者元素使用单引号。如下所示:
1 2 |
(lldb) command [subcommand] -option "some "quoted" string"
(lldb) command [subcommand] -option ‘some "quoted" string‘
|
这种命令解析设计规范了LLDB命令语法,并对所有命令做了个统一。
命令选项
LLDB中的命令选项有规范形式和缩写形式两种格式。以设置断点的命令breakpoint set为例,以下列表了其部分选项的格式,其中括号中的是规范形式:
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> )
…</function-name></function-name></linenum></linenum></filename></filename></function-name></function-name></selector></selector></method></method>
各选项的顺序是任意的。如果后面的参数是以”–“开头的,则在选项后面添加”—“作为选项的终止信号,以告诉LLDB我们处理的选项的正确位置。如下命令所示:
(lldb)
process launch --stop-at-entry -- -program_arg_1 value -program_arg_2 value
如上所示,命令的选项是—stop-at-entry,参数是-program_arg_1和-program_arg_2,我们使用”—“将选项与参数作一下区分。
原始命令
LLDB命令解析器支持”原始(raw)“命令,即没有命令选项,命令字符串的剩余部分未经解析就传递给命令。例如,expression就是一个原始命令。
不过原始命令也可以有选项,如果命令字符串中有虚线,则在命令名与命令字符串之间放置一个选项结束符(—)来表明没有命令标记。
我们可以通过help命令的输出来查看一个命令是否是原始命令。
命令补全(Command Completion)
LLDB支持源文件名,符号名,文件名,等等的命令补全(Commmand Completion)。终端窗口中的补全是通过在命令行中输入一个制表符来初始化的。Xcode控制台中的补全与在源码编辑器中的补全方式是一样的:补全会在第三个字符被键入时自动弹出,或者通过Esc键手动弹出。
一个命令中的私有选项可以有不同的完成者(completers)。如breakpoint中的—file 选项作为源文件的完成者,—shlib 选项作为当前加载的库的完成者,等等。这些行为是特定的,例如,如果指定—shlib ,且以—file 结尾,则LLDB只会列出由—shlib 指定的共享类库。
Python脚本
对于高级用户来说,LLDB有一个内置的Python解析器,可以通过脚本命令来访问。调试器中的所有特性在Python解析器中都可以作为类来访问。这样,我们就可以使用LLDB-Python库来写Python函数,并通过脚本将其加载到运行会话中,以执行一些更复杂的调试操作。
在命令行中调试程序
通常我们都是在Xcode中直接使用LLDB调试器,Xcode会帮我们完成很多操作。当然,如果我们想让自己看着更Bigger,或者想了解下调试器具体的一些流程,就可以试试直接在终端使用LLDB命令来调试程序。在终端中使用LLDB调试器,我们需要了解以下内容:
1.加载程序以备调试
2.将一个运行的程序绑定到LLDB
3.设置断点和观察点
4.控制程序的执行
5.在调试的程序中导航
6.检查状态和值的变量
7.执行替代代码
了解在终端中这些操作是如何进行的,可以帮助我们更深入的了解调试器在Xcode中是如何运作的。下面我们分步来介绍一下。
指定需要调试的程序
首先我们需要设置需要调试的程序。我们可以使用如下命令做到这一点:
1 2 |
$ lldb /Projects/Sketch/build/Debug/Sketch.app
Current executable set to ‘/Projects/Sketch/build/Debug/Sketch.app‘ (x86_64).
|
或者在运行lldb后,使用file命令来处理,如下所示:
1 2 3 |
$ lldb
(lldb) file /Projects/Sketch/build/Debug/Sketch.app
Current executable set to ‘/Projects/Sketch/build/Debug/Sketch.app‘ (x86_64).
|
设置断点
在设置完程序后,我们可能想设置一点断点来调试程序。此时我们可以使用breakpoint set命令来设置断点,这个命令简单、直观,且有智能补全,接下来我们看看它的具体操作。
如果想在某个文件中的某行设置一个断点,可使用以下命令:
1 |
(lldb) breakpoint set --file foo.c --line 12
|
如果想给某个函数设置断点,可使用以下命令:
1 |
(lldb) breakpoint set --name foo
|
如果想给C++中所有命名为foo的方法设置断点,可以使用以下命令:
1 |
(lldb) breakpoint set --method foo
|
如果想给Objective-C中所有命名为alignLeftEdges:的选择器设置断点,则可以使用以下命令:
1 |
(lldb) breakpoint set --selector alignLeftEdges:
|
我们可以使用—shlib 来将断点限定在一个特定的可执行库中:
1 |
(lldb) breakpoint set --shlib foo.dylib --name foo
|
看吧,断点设置命令还是很强大的。
如果我们想查看程序中所有的断点,则可以使用breakpoint list命令,如下所示: