原文
本章描述的命令允许你查询程序中定义的符号(变量名、函数名和类型)。 此信息是程序文本中固有的,不会随着程序执行而改变。 GDB 在程序的符号表中、在启动 GDB 时指示的文件中找到它(参见选择文件部分),或者通过文件管理命令之一(参见指定文件的命令部分)。
有时,你可能需要引用包含异常字符的符号,GDB 通常将其视为单词分隔符。 最常见的情况是引用其他源文件中的静态变量(参见程序变量部分)。 文件名作为调试符号记录在目标文件中,但 GDB 通常会将一个典型的文件名,如foo.c
解析为三个单词foo
, .
, c
。 要让 GDB 将 foo.c
识别为单个符号,请将其括在单引号中; 例如,
p 'foo.c' ::x
在文件foo.c
的范围内查找 x 的值。
info address symbol
描述符号数据的存储位置。 对于寄存器变量,这表示它保存在哪个寄存器中。对于非寄存器局部变量,这将打印始终存储变量的堆栈帧偏移量。 注意与print &symbol
的对比,它对寄存器变量根本不起作用,而对于堆栈局部变量则打印变量当前实例化的确切地址。
info symbol addr
打印存储在地址 addr 中的符号名称。 如果没有符号准确存储在 addr 处,GDB 会打印最近的符号和它的偏移量:
(gdb) info symbol 0x54320
_initialize_vx + 396 in section .text
这与 info address
命令相反。 你可以使用它来找出变量名或给定地址的函数名。
whatis expr
打印表达式 expr 的数据类型。 expr 并没有被实际计算,并且它内部的任何副作用操作(例如赋值或函数调用)都不会发生。 请参阅章节表达式。
whatis
打印 $ 的数据类型,值历史中的最后一个值。
ptype typename
打印数据类型 typename 的描述。 typename 可能是类型的名称,或者对于 C 代码,它可能具有“class class-name”、“struct struct-tag”、“union union-tag”或“enum enum-tag”的形式。
ptype expr
ptype
打印表达式 expr 类型的描述。 ptype 与 whatis 的不同之处在于打印详细描述,而不仅仅是类型的名称。 例如,对于这个变量声明:
struct complex {double real; double imag;} v;
两个命令的输出分别如下:
(gdb) whatis v
type = struct complex
(gdb) ptype v
type = struct complex {
double real;
double imag;
}
与 whatis 一样,使用不带参数的 ptype 指的是 $ 的类型,即值历史中的最后一个值。
info types regexp
info types
打印名称与 regexp 匹配的所有类型(或程序中的所有类型,如果不提供参数)的简要说明。 每个完整的类型名都被匹配,就好像它是一个完整的行; 因此,i type value
给出程序中名称包含字符串值的所有类型的信息,但i type ^value$
仅给出完整名称为value 的类型的信息。 这个命令和ptype有两点不同:第一,和whatis一样,不打印详细说明; 其次,它列出了定义了类型的所有源文件。
info scope addr
列出特定范围内的所有局部变量。 这个命令接受一个位置——一个函数名、一个源代码行或一个以“*”开头的地址,并打印出该位置定义的范围内的所有局部变量。 例如:
(gdb) info scope command_line_handler
Scope for command_line_handler:
Symbol rl is an argument at stack/frame offset 8, length 4.
Symbol linebuffer is in static storage at address 0x150a18, length 4.
Symbol linelength is in static storage at address 0x150a1c, length 4.
Symbol p is a local variable in register $esi, length 4.
Symbol p1 is a local variable in register $ebx, length 4.
Symbol nline is a local variable in register $edx, length 4.
Symbol repeat is a local variable at frame offset -8, length 4.
此命令对于确定在跟踪实验期间要收集的数据特别有用,请参阅章节跟踪点操作列表。
info source
显示当前源文件的名称——即包含当前执行点的函数的源文件——以及编写它的语言。
info sources
打印程序中包含调试信息的所有源文件的名称,分为两个列表:已读取符号的文件和需要时将读取符号的文件。
info functions
打印所有定义函数的名称和数据类型。
info functions regexp
打印名称包含正则表达式 regexp 匹配项的所有已定义函数的名称和数据类型。 因此,info fun step
会找到名称中包含 step 的所有函数; info fun ^step
查找名称以 step 开头的那些。
info variables
打印在函数外部声明的所有变量的名称和数据类型(不包括局部变量)。
info variables regexp
打印名称包含正则表达式 regexp 匹配项的所有变量(局部变量除外)的名称和数据类型。某些系统允许在不停止和重新启动程序的情况下替换组成程序的各个目标文件。例如,在 VxWorks 中,你可以简单地重新编译有缺陷的目标文件并继续运行。如果你在这些系统之一上运行,你可以允许 GDB 重新加载自动重新链接模块的符号:
set opaque-type-resolution on
告诉 GDB 解析不透明类型。 不透明类型是一种声明为指向结构、类或联合的指针的类型——例如,struct MyType *
— 在一个源文件中使用,尽管 struct MyType
的完整声明在另一个源文件中。 默认为开启。 在下一次加载文件的符号之前,对此子命令设置的更改不会生效。
set opaque-type-resolution off
告诉 GDB 不要解析不透明类型。 在这种情况下,类型打印如下:
{
show opaque-type-resolution
显示是否解析不透明类型。
maint print symbols filename
maint print psymbols filename
maint print msymbols filename
将调试符号数据的转储写入文件 filename。这些命令用于调试 GDB 符号读取代码。仅包含带有调试数据的符号。如果你使用maint print symbols
,GDB 将包含它已经收集了完整详细信息的所有符号:也就是说,filename 仅反映那些 GDB 已读取其符号的文件的符号。你可以使用命令 info sources
找出这些文件是哪些文件。如果你改用maint print psymbols
,则转储会显示有关 GDB 仅不完全了解的符号的信息——即 GDB 已略读但尚未完全读取的文件中定义的符号。最后,maint print msymbols
只转储 GDB 从中读取一些符号的每个目标文件所需的最少符号信息。有关 GDB 如何读取符号的讨论(在符号文件的描述中),请参阅特殊文件的命令一节。