第三章 GDB命令(未校正)
如果缩写明确,您可以将GDB命令缩写为命令全名的前几个字母;只需输入RET,就可以重复某些GDB命令。您还可以使用TAB键让GDB补全命令中的剩余字母(如果有多种可能性的话,会向您显示可用的替代选项)。
3.1 命令语法
GDB命令是单行输入。不限制命令长度。它以一个命令名开始,后面跟着一些参数,这些参数的含义取决于命令名。例如,命令step接受一个参数,该参数是步进的次数,如"step 5"。您也可以使用不带参数的step命令。有些命令不带任何参数。
如果缩写明确的话,GDB命令名可以缩写。其他可能的命令缩写在各个命令的文档中列出。在某些情况下,甚至允许使用模棱两可的缩写;例如,s特指step命令,即使还有其他命令的名称以s开头。您可以使用命令缩写作为help命令的参数来测试命令缩写。
一个空白行作为GDB的输入(只输入RET)意味着重复前面的命令。但某些命令(比如run)不会这样重复;这些命令的无意重复可能会引起麻烦,而且您可能并不想重复这些命令。用户定义的命令可以禁用此功能;参见第357页第23.1.1节[定义]。
当您用RET重复list和x命令时,它们会构造新的参数,而不是简单地重复输入的内容。这会使扫描源或存储器变得更容易。
GDB中的RET命令还有一种用法:对冗长的输出进行分区,该方法与more命令一样(参见第340页第22.4节[屏幕尺寸])。由于在这种情况下很容易按下太多RET,GDB禁止在任何产生这种显示的命令后重复命令。
从 # 到行尾的任何文本都是注释;它什么也不做。这主要在命令文件中有用(参见第23.1.3节[命令文件],第361页)。
Ctrl-o绑定对于重复复杂的命令序列很有用。该命令接受当前行,如RET,然后从历史中获取相对于当前行的下一行进行编辑。
3.2 命令设置
许多命令根据特定于命令的变量或设置来改变它们的行为。这些设置可以通过set子命令进行更改。例如,print命令(见第10章[检查数据],第131页)打印数组的方式不同,这取决于可通过set print elements NUMBER-OF-ELEMENTS和set print array-indexes等命令进行更改的设置值。
您可以在GDB启动时加载的gdbinit文件中根据自己的喜好更改这些设置。参见第16页第2.1.3节【启动】。
这些设置也可以在调试会话期间交互更改。例如,要更改要打印的数组元素的限制,可以执行以下操作:
(gdb) set print elements 10
(gdb) print some_array
$1 = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90...}
上述set print elements 10命令将要打印的元素数量从默认值200更改为10。如果您只打算将10的限制用于打印some_array,那么您必须使用set print elements 200将限制恢复到200。
有些命令允许用命令选项覆盖设置。例如,print命令支持许多选项,这些选项允许覆盖由set print子命令设置的相关全局打印设置。参见第131页的[打印选项]。上面的例子可以改写为:
(gdb) print -elements 10 -- some_array
$1 = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90...}
或者,您可以使用with命令在命令调用期间临时更改设置。
with setting [value] [-- command]
w setting [value] [-- command]
在命令持续时间内,暂时将setting设置为value。
setting是您可以使用set子命令更改的任何设置。value是运行command时分配给setting的值。
如果没有提供command,则重复执行最后一个命令。
如果提供了命令,则命令前面必须有双破折号(--)分隔符。这是必需的,因为有些设置接受自由格式的参数,如expressions或filenames。
例如,命令
(gdb) with print array on -- print some_array
相当于以下3个命令:
(gdb) set print array on
(gdb) print some_array
(gdb) set print array off
如果您希望在运行用户自定义的命令或Python、Guile中定义的命令时覆盖某个设置,with命令特别有用。参见第23章【延伸GDB】,第357页。
(gdb) with print pretty on -- my_complex_command
要为同一个命令更改多个设置,可以嵌套with命令。例如,with language ada-with print elements 10暂时将语言更改为Ada,并为数组和字符串设置10个元素的打印限制。
3.3 命令补全
如果缩写仅对应一种命令,GDB可以为您自动补全命令;它还可以随时显示命令中下一个单词的有效可能结果。这适用于GDB命令、GDB子命令、命令选项和程序中的符号名称。
只要你想让GDB补全一个单词的剩余部分,就按TAB键。如果缩写仅对应一种命令,GDB补全单词,然后等你完成命令(或者按RET键输入)。例如,如果您键入
(gdb) info bre TAB GDB填充单词"breakpoints"的剩余部分,因为这是唯一以"bre"开头的info子命令:
(gdb) info breakpoints
如果"breakpoints"看起来不像您想要的命令,您可以在此时按RET来运行info breakpoints命令,或者退格并输入其他内容。(如果您确定您首先想要info breakpoints,那么您最好在"info bre"之后立即键入RET,以利用命令缩写而不是命令补全)。
如果当你按TAB键时,下一个单词有不止一种可能,GDB就会发出警告。您可以继续输入更多字符并重试,或者只需再次按TAB键;GDB显示该单词所有可能的补全。例如,您可能想在一个名称以"make_"开头的子例程上设置一个断点,但是当您键入b make_TAB时,GDB只是发出警告。再次键入TAB会显示程序中以这些字符开头的所有函数名,例如:
(gdb) b make_ TAB
gdb sounds bell; press TAB again, to see:
make_a_section_from_file make_environ
make_abs_section make_function_type
make_blockvector make_pointer_type
make_cleanup make_reference_type
make_command make_symbol_completion_list
(gdb) b make_
在显示了可用的可能结果之后,GDB复制你的部分输入(在这个例子中是"b make_"),这样你就可以完成这个命令了。
如果你只是想在第一时间看到候选名单,可以按M-? 而不是按两次TAB键。M-? 意思是META?。您可以通过在键入时按住键盘上指定为META shift的键(如果有)来键入 ? ,还是作为 ESC 后跟 ?
如果可能补全的数量很大,GDB将打印尽可能多的列表,并显示一条消息,指示列表可能被截断。
(gdb) b mTABTAB
main
<... the rest of the possible completions ...>
*** List may be truncated, max-completions reached. ***
(gdb) b m
这种行为可以通过以下命令来控制:
set max-completions limit
set max-completions unlimited
设置补全候选对象的最大数量。一旦GDB收集了这么多的候选对象,它将停止寻找更多的补全对象。这在补全函数名之类的事情时很有用,因为收集所有可能的候选对象可能会很耗时。默认值为200。设置为零值时禁用tab补全功能。请注意,设置无限制或非常大的限制都会使补全速度变慢。
show max-completions
显示GDB将收集并在完成时显示的候选对象的最大数量。
有时你需要的字符串,虽然在逻辑上是一个"单词",但可能包含括号或其他字符,GDB通常会将其排除在单词概念之外。在这种情况下,为了允许单词补全有效,您可以在GDB命令中用'(单引号)把单词括起来。
您可能需要这样做的一种场景是,键入一个表达式,该表达式包含一个带有模板参数的C++符号名。这是因为当完成表达式时,GDB将"<"字符视为单词分隔符,假设它是小于比较运算符(参见第217页15.4.1.1节[C和C++运算符])。
例如,当您想要使用print或call命令交互式地调用C++模板函数时,您可能需要区分您是指专用于int的name版本,name
(gdb) p ' func< M-?
func<int>() func<float>()
(gdb) p 'func<
然而,当设置断点时(参见第118页第9.2节[指定位置]),通常不需要在函数名前输入引号,因为gdb知道您想要在函数上设置断点:
(gdb) b func< M-?
func<int>() func<float>()
(gdb) b func<
即使在键入C++重载函数的名称的情况下也是如此(同一函数的多个定义,按参数类型区分)。例如,当您想要设置一个断点时,您不需要区分您是指采用int参数的name版本,还是采用float参数的name版本。
(gdb) b bubble( M-?
bubble(int) bubble(double)
(gdb) b bubble(dou M-?
bubble(double)
请参阅第245页的[引用名称],了解需要引用的其他场景的描述。
有关重载函数的更多信息,请参见第220页的15.4.1.3节。您可以使用setoverload-resolutionoff命令禁用重载解析;参见第221页的15.4.1.7一节。
当在查询结构中的字段的表达式中完成时,gdb还试图将完成限制在左侧类型中可用的字段名:
(gdb) p gdb_stdout.M-?
magic to_fputs to_rewind
to_data to_isatty to_write
to_delete to_put to_write_async_safe
to_flush to_read
这是因为gdb_stdout是struct ui_file类型的变量,在GDB源文件中定义如下:
struct ui_file
{
int *magic;
ui_file_flush_ftype *to_flush;
ui_file_write_ftype *to_write;
ui_file_write_async_safe_ftype *to_write_async_safe;
ui_file_fputs_ftype *to_fputs;
ui_file_read_ftype *to_read;
ui_file_delete_ftype *to_delete;
ui_file_isatty_ftype *to_isatty;
ui_file_rewind_ftype *to_rewind;
ui_file_put_ftype *to_put;
void *to_data;
}
3.4 命令选项
有些命令可以接受以前破折号开始的命令选项。例如,print -pretty. 。与命令名类似,您可以将一个GDB选项缩写为选项名的前几个字母,如果该缩写明确的话,您还可以使用TAB键让GDB自动补全该选项名(或者向您显示可用的选项,如果有多种可能性的话)。
有些命令将原始输入作为参数。例如,print命令处理GDB支持的任意语言的任意表达式。对于这样的命令,因为原始输入可能以前破折号开始,这将与选项或其任何缩写相混淆,例如。print -p(print -pretty或打印小写p?),如果指定任何命令选项,则必须使用双破折号(--)分隔符来指示选项的结束。
有些选项被描述为接受一个可以on也可以off的参数。这些被称为布尔选项。与布尔设置命令类似,on和off是典型值,但1、yes和enable中的任何一个也可以用作“真”值,0、no和disable中的任何一个也可以用作“假”值。您也可以省略“真”值,因为它是默认隐含的。
例如,这些是等价的:
(gdb) print -object on -pretty off -element unlimited -- *myptr
(gdb) p -o -p 0 -e u -- *myptr
在命令名后面,您可以通过打开补全发现一些命令选项。例如:
(gdb) print -TABTAB
-address -max-depth -raw-values -union
-array -null-stop -repeats -vtbl
-array-indexes -object -static-members
-elements -pretty -symbol
在某些情况下,补全会给你一个建议,告诉你一个选项期望什么样的参数。例如:
(gdb) print -elements TABTAB
NUMBER unlimited
这里,选项需要一个数字(例如100),不是字面上的NUMBER。 这种metasyntactical参数总是以大写形式出现。
(有关使用print命令的更多信息,请参见第131页第10章[检查数据]。
3.5 自动为用户定义的别名添加默认参数
您可以告诉GDB在使用用户定义的别名时,总是在用户显式提供的参数列表前添加一些默认参数。
如果您对一个命令重复使用相同的参数或选项,您可以为此命令定义一个别名,并告诉GDB在使用别名时自动将这些参数或选项添加到您显式键入的参数列表中。
例如,如果您经常使用thread apply all命令指定以升序对线程进行操作,并在遇到错误时继续操作,您可以告诉GDB使用以下命令自动预先设置 -ascending 和 -c 选项:
(gdb) alias thread apply asc-all = thread apply all -ascending -c
一旦用默认参数定义了这个别名,任何时候您键入thread apply asc-all并后跟some arguments,GDB都会执行thread apply all -ascending -c some arguments。
为了减少输入,您还可以定义一个单词别名:
(gdb) alias t_a_c = thread apply all -ascending -c
通常,明确的缩写可以用于别名和默认参数。
命令的不同别名不共享它们的默认参数。例如,您可以使用以下命令定义一个显示所有可能信息的新别名bt_ALL和一个显示非常有限信息的别名bt_SMALL:
(gdb) alias bt_ALL = backtrace -entry-values both -frame-arg all
-past-main -past-entry -full
(gdb) alias bt_SMALL = backtrace -entry-values no -frame-arg none
-past-main off -past-entry off
(有关使用别名命令的更多信息,请参见第503页第23.6节[别名]。
默认参数不限于命令的参数和选项,但如果命令接受嵌套命令作为参数,则可以指定嵌套命令。例如,下面定义了faalocalsoftype,
它列出了具有特定类型局部变量的帧,以及匹配的局部变量:
(gdb) alias faalocalsoftype = frame apply all info locals -q -t
(gdb) faalocalsoftype int
#1 0x55554f5e in sleeper_or_burner (v=0xdf50) at sleepers.c:86
i = 0
ret = 21845
这对于定义一组嵌套with命令的别名也非常有用,这些命令具有特定的临时设置组合。例如,下面定义了别名pp10,它很好地打印了一个表达式参数,如果表达式是字符串或数组,则最多有10个元素:
(gdb) alias pp10 = with print pretty -- with print elements 10 -- print
这将别名pp10定义为3个命令的序列。第一部分with print pretty -- 临时启动设置set print pretty,然后启动分隔符 -- 后面的命令。第一部分后面的命令也是一个with命令,它临时将set print elements设置更改为10,然后启动第二个分隔符 -- 后面的命令。第三部分print是pp10别名将启动的命令,使用设置的临时值和用户明确给出的参数。有关带命令用法的更多信息,请参见第21页第3.2节[命令设置]。
3.6 获取帮助
您总是可以使用命令help向GDB本身查询关于其命令的帮助信息。
help
h 您可以使用不带参数的help(缩写为h)来显示命令的命名类的简短列表:
(gdb) help
List of classes of commands:
aliases -- User-defined aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without
stopping the program
user-defined -- User-defined commands
Type "help" followed by a class name for a list of
commands in that class.
Type "help" followed by command name for full
documentation.
Command name abbreviations are allowed if unambiguous.
(gdb)
help class
使用一个常规帮助类作为参数,您可以获得该类中各个命令的列表。如果一个命令有别名,别名在命令名之后给出,用逗号分隔。如果别名有默认参数,别名的完整定义在第一行之后给出。例如,下面是类status的帮助显示:
(gdb) help status
Status inquiries.
List of commands:
info, inf, i -- Generic command for showing things
about the program being debugged
info address, iamain -- Describe where symbol SYM is stored.
alias iamain = info address main
info all-registers -- List of all registers and their contents,
for selected stack frame.
...
show, info set -- Generic command for showing things
about the debugger
Type "help" followed by command name for full
documentation.
Command name abbreviations are allowed if unambiguous.
(gdb)
help command
用命令名作为help参数,GDB显示一个关于如何使用该命令的简短段落。如果该命令有一个或多个别名,GDB将显示第一行命令名及其所有别名,用逗号分隔。第一行后面是所有具有默认参数的别名的完整定义。
apropos [-v] regexp
apropos命令在所有GDB命令及其文档中搜索args中指定的正则表达式。它打印出所有找到的匹配。代表"verbose"的可选标志"-v"表示输出匹配命令的完整文档,并突出显示匹配正则表达式的文档部分。例如:
apropos alias
结果是:
alias -- Define a new command that is an alias of an existing command
aliases -- User-defined aliases of other commands
而
apropos -v cut.*thread apply
结果显示在下面的输出中,如果启用了样式,则会突出显示"cut for"和"thread apply"。
taas -- Apply a command to all threads (ignoring errors
and empty output).
Usage: taas COMMAND
shortcut for ’thread apply all -s COMMAND’
tfaas -- Apply a command to all frames of all threads
(ignoring errors and empty output).
Usage: tfaas COMMAND
shortcut for ’thread apply all -s frame apply all -s COMMAND’
complete args
complete args命令列出了命令开头的所有可能的补全。使用参数指定要补全的命令的开头。例如:
complete i
结果是:
if
ignore
info
inspect
这是供GNU Emacs使用的。
除了help,你可以使用gdb命令info和show来查询你的程序的状态,或者GDB本身的状态。每个命令支持许多查询主题;本手册在适当的上下文中介绍了它们。"命令"、"变量"和"函数索引"中"info"和"show"下的列表指向所有子命令。参见第839页的[命令和变量索引]。
info
这个命令(缩写为i)用于描述你的程序的状态。例如,您可以使用info args显示传递给函数的参数,列出当前与info registers一起使用的寄存器,或者列出您使用info breakpoints设置的断点。您可以使用help info获得info子命令的完整列表。
set
可以用set将表达式的结果赋给一个环境变量。例如,您可以用set prompt (** 将GDB提示设置为)-sign。
show
与 info相反,show用于描述GDB本身的状态。通过使用相关的命令set,您可以更改大多数可以show的内容;例如,您可以用set radix控制使用什么数字系统来进行显示,或者简单地用 show radix查询当前显示。
要显示所有可设置参数及其当前值,可以使用不带参数的show,您也可以使用info set。两个命令产生相同的显示。
这里有几个杂七杂八的show子命令,它们都是例外,缺少相应的set命令:
show version
显示GDB的运行版本。您应该在GDB bug-reports中包含这些信息。如果您的站点使用多个版本的GDB,您可能需要确定您运行的是哪个版本的GDB;随着GDB的发展,新的命令被引入,旧的命令可能会消失。此外,许多系统供应商提供GDB的变体版本,GNU/Linux发行版中也有GDB的变体版本。版本号和你启动GDB时公布的一样。
show copying
info copying
显示关于复制GDB权限的信息。
show warranty
info warranty
显示GNU的"无保修"声明,或者保修,如果你的GDB版本有保修的话。
show configuration
显示GDB构建时配置方式的详细信息。这将显示传递给configure脚本的可选参数以及配置自动检测到的configure**参数。当报告一个GDB bug时(见第31章gdb bug,第631页),在你的报告中包含这些信息是很重要的。