使用 func 或 file 命令时,可能需要使用作用域转换操作符来限定作为目标给出的函数的名称。
dbx 提供了三个用于限定符号的作用域转换操作符:反引号操作符 (`)、C++ 双冒号操作符 (::) 和块局部操作符 (:lineno)。应单独使用它们,在某些情况下可以一起使用。
除了在代码中导航时限定文件名和函数名外,打印和显示作用域外变量和表达式以及显示类型和类声明时还必须限定符号名(使用 whatis 命令)。在所有情况下,符号限定规则都是相同的;本节介绍所有类型的符号名限定的规则。
使用反引号字符 (`) 可查找全局作用域变量或函数:
(dbx) print `item |
一个程序可以在两个不同的文件(或编译模块)中使用同一函数名。在这种情况下,还必须将函数名限定到 dbx,以便它记录您要导航的函数。要按相应的文件名限定函数名,请使用通用反引号 (`) 作用域转换操作符。
(dbx) func`file_name`function_name |
使用双冒号操作符 (::) 可以用以下名称限定具有全局作用域的 C++ 成员函数、顶级函数或变量:
重载名(不同参数类型使用同一名称)
二义名(不同类中使用同一名称)
可能需要限定重载函数名。如果不限定它,则 dbx 会显示一个重载列表,以便您从中选择要导航的函数。如果您知道函数类名,则可以将其与双冒号作用域转换操作符一起使用来限定名称。
(dbx) func class::function_name (args) |
例如,如果 hand 是类名,而 draw 是函数名,请键入:
(dbx) func hand::draw |
使用块局部操作符 (: line_number) 可专门引用嵌套块中的变量。如果有遮蔽参数或成员名的局部变量,或如果有几个块,其中每个块都有其自己的局部变量版本,可能需要这样做。line_number 是相关变量所对应的块内第一行代码的号码。当 dbx 使用块局部操作符限定局部变量时,dbx 会使用第一个代码块的行号,但您可以在 dbx 表达式中使用作用域内的任意行号。
在下例中,块局部操作符 (:230) 与反引号操作符配合使用。
(dbx) stop in `animate.o`change_glyph:230`item |
下例显示了当函数中有多个具体值时,dbx 如何对使用块局部操作符限定的变量名求值。
(dbx) list 1,$ 1 #include <stddef.h> 2 3 int main(int argc, char** argv) { 4 5 int i=1; 6 7 { 8 int i=2; 9 { 10 int j=4; 11 int i=3; 12 printf("hello"); 13 } 14 printf("world\n"); 15 } 16 printf("hi\n"); 17 } 18 (dbx) whereis i variable: `a.out`t.c`main`i variable: `a.out`t.c`main:8`i variable: `a.out`t.`main:10`i (dbx) stop at 12 ; run ... (dbx) print i i = 3 (dbx) which i `a.out`t.c`main:10`i (dbx) print `main:7`i `a.out`t.c`main`i = 1 (dbx) print `main:8`i `a.out`t.c`main:8`i = 2 (dbx) print `main:10`i `a.out`t.c`main:10`i = 3 (dbx) print `main:14`i `a.out`t.c`main:8`i = 2 (dbx) print `main:15`i `a.out`t.c`main`i = 1 |
dbx 提供了一种按链接程序名(在 C++ 中为损坏名)查找符号的特殊语法。使用 #(磅符号)字符作为符号名的前缀(在任何 $(美元符号)字符前使用 ksh 转义符 \(反斜线)),如以下示例中所示:
(dbx) stop in #.mul (dbx) whatis #\$FEcopyPc (dbx) print `foo.c`#staticvar |