Hexagon GDB Debugger介绍(34)
2.16 检查符号表
本章描述的命令允许你查询程序中定义的符号(变量名、函数名和类型)。 此信息是程序文本中固有的,不会随着程序执行而改变。 调试器在你的程序符号表中、在你启动调试器时指示的文件中(参见第 2.3 节)或通过文件管理命令之一(参见第 2.18.1 节,还在后面,没翻译出来)找到它。
有时,你可能需要引用包含异常字符的符号,调试器通常将其视为单词定界符。 最常见的情况是引用其他源文件中的静态变量(参见第 2.12.2 节)。 文件名作为调试符号记录在目标文件中,但调试器通常会将典型的文件名(如 foo.c)解析为三个单词 foo.C。 要让调试器将 foo.c 识别为单个符号,请将其括在单引号中; 例如:
p 'foo.c'::x
在文件 foo.c 的范围内查找 x 的值。
info address symbol
描述符号数据的存储位置。 对于寄存器变量,这表示它保存在哪个寄存器中。对于非寄存器局部变量,这将打印始终存储变量的堆栈帧偏移量。
请注意与 print &symbol 的对比,它对寄存器变量根本不起作用,而对于堆栈局部变量则打印变量当前实例化的确切地址。
info symbol addr
打印存储在地址 addr 中的符号名称。 如果没有符号准确存储在 addr 处,调试器将打印最近的符号和它的偏移量:
(hexagon-gdb) info symbol 0x54320
_initialize_vx + 396 in section .text
这与 info address 命令相反。 你可以使用它来找出变量名或给定地址的函数名。
whatis expr
打印表达式 expr 的数据类型。 expr 并没有被实际计算,并且它内部的任何副作用操作(例如赋值或函数调用)都不会发生。 见第 2.12.1 节。
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;
这两个命令给出了这个输出:
(hexagon-gdb) whatis v
type = struct complex
(hexagon-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
列出特定范围内的所有局部变量。 此命令接受一个位置:函数名称、源代码行或以 * 开头的地址,并打印该位置定义的范围内的所有局部变量。 例如:
(hexagon-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.
此命令对于确定在跟踪实验期间收集哪些数据特别有用,请参阅第 2.14.1.4 节。
info source
显示有关当前源文件的信息:即包含当前执行点的函数的源文件:
- 源文件的名称和包含它的目录
- 编译的目录
- 长度(以行为单位)
- 它是用哪种编程语言编写的
- 可执行文件是否包含该文件的调试信息,如果包含,信息的格式(例如 STABS、Dwarf 2 等)
- 调试信息是否包含有关预处理器宏的信息
info sources
打印程序中包含调试信息的所有源文件的名称,分为两个列表:已读取符号的文件和需要时将读取符号的文件。
info functions
打印所有定义函数的名称和数据类型。
info functions regexp
打印名称包含正则表达式 regexp 匹配项的所有已定义函数的名称和数据类型。 因此, info fun step 查找名称中包含 step 的所有函数; info fun ^step 查找名称以 step 开头的名称。 如果函数名包含与正则表达式语言冲突的字符(例如,.operator*()),可以用反斜杠引用它们。
info variables
打印在函数外声明的所有变量的名称和数据类型(即不包括局部变量)。
info variables regexp
打印名称包含正则表达式 regexp 匹配项的所有变量(局部变量除外)的名称和数据类型。
set opaque-type-resolution on
告诉调试器解析不透明类型。 不透明类型是声明为指向结构、类或联合的指针的类型。 例如,struct MyType * 可以在一个源文件中使用,尽管 struct MyType 的完整声明在另一个源文件中。 默认为开启。
在下一次加载文件的符号之前,对此子命令设置的更改不会生效。
set opaque-type-resolution off
告诉调试器不要解析不透明类型。 在这种情况下,类型打印如下:
{<no data fields>}
show opaque-type-resolution
显示是否解析不透明类型。
maint print symbols filename
maint print psymbols filename
maint print msymbols filename
将调试符号数据的转储写入文件 filename。 这些命令用于调试调试器的符号读取代码。 仅包含带有调试数据的符号。 如果你使用 maint 打印符号,调试器将包括它已经收集完整详细信息的所有符号:也就是说,文件名仅反映调试器已读取其符号的那些文件的符号。 你可以使用命令 info sources 找出这些文件是哪些文件。 如果你改用 maint print psymbols,则转储会显示有关调试器仅部分了解的符号的信息:即调试器已略读但尚未完全读取的文件中定义的符号。 最后,maint print msymbols 只转储调试器从中读取一些符号的每个目标文件所需的最少符号信息。 有关调试器如何读取符号的讨论(在符号文件的描述中),请参见第 2.18.1 节。
maint info symtabs [ regexp ]
maint info psymtabs [ regexp ]
列出名称与 regexp 匹配的 struct symtab 或 struct partial_symtab 结构。 如果未给出正则表达式,则将其全部列出。 输出包括你可以复制到调试器中以更详细地检查特定结构的表达式。 例如:
(hexagon-gdb) maint info psymtabs dwarf2read
{ objfile /home/gnu/build/gdb/gdb
((struct objfile *) 0x82e69d0)
{ psymtab /home/gnu/src/gdb/dwarf2read.c
((struct partial_symtab *) 0x8474b10)
readin no
fullname (null)
text addresses 0x814d3c8 -- 0x8158074
globals (* (struct partial_symbol **) 0x8507a08 @ 9)
statics (* (struct partial_symbol **) 0x40e95b78 @ 2882)
dependencies (none)
}
}
(hexagon-gdb) maint info symtabs
(hexagon-gdb)
我们看到有一个部分符号表,其文件名包含字符串 dwarf2read,属于调试器可执行文件; 我们看到调试器还没有读入任何符号表。
如果我们在函数上设置断点,将导致调试器读取包含该函数的编译单元的符号表:
(hexagon-gdb) break dwarf2_psymtab_to_symtab
Breakpoint 1 at 0x814e5da: file
/home/gnu/src/gdb/dwarf2read.c,
line 1574.
(hexagon-gdb) maint info symtabs
{ objfile /home/gnu/build/gdb/gdb
((struct objfile *) 0x82e69d0)
{ symtab /home/gnu/src/gdb/dwarf2read.c
((struct symtab *) 0x86c1f38)
dirname (null)
fullname (null)
blockvector ((struct blockvector *) 0x86c1bd0) (primary)
debugformat DWARF 2
}
}
(hexagon-gdb)