使用 func 或 file 命令时,可能需要使用作用域转换操作符来限定作为目标给出的函数的名称。
dbx 提供了三个用于限定符号的作用域转换操作符:反引号操作符 (`)、C++ 双冒号操作符 (::) 和块局部操作符 (:lineno)。应单独使用它们,在某些情况下可以一起使用。
除了在代码中导航时限定文件名和函数名外,输出和显示作用域外变量和表达式以及显示类型和类声明时还必须限定符号名(使用 whatis 命令)。
本节介绍了所有各类符号名称限定的规则。符号限定规则在所有情况下都是相同的。
使用反引号字符 (`) 可查找全局作用域变量或函数:
(dbx) print `item
一个程序可以在两个不同的文件或编译模块中使用同一函数名。在这种情况下,还必须将函数名限定到 dbx,以便它记录您要导航的函数。要按相应的文件名限定函数名,请使用通用反引号 (`) 作用域转换操作符。
(dbx) func`filename`function-name
如果不限定重载函数名称,则 dbx 会显示一个重载列表,以便您从中选择要导航的函数。如果您知道函数类名,则可以将其与双冒号作用域转换操作符一起使用来限定名称。
(dbx) func class::function-name (args)
例如,如果 hand 是类名,而 draw 是函数名:
(dbx) func hand::draw
使用块局部操作符 (: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