某些语言,例如C和C++,提供定义和引用“预处理宏”的方法,这些宏可以展开为符号串。GDB 可以计算包含宏的表达式,显示宏展开的
结果,并 且显示宏的定义,包括在何处定义的。
可能需要特别编译程序来给GDB提供预处理宏的信息。大多数编译器在调试信息中不包括宏,即使编译时使用’-g’选项。
程序可能在某个点定义一个宏,在后面删除这个定义,然后在此后给这个宏提供另外的定义 。因此,在程序里不同点上,同一个宏可能
有不同的定义,或者根本就没有定义。如果在当前堆栈帧上,GDB 使用这个帧源代码行范围的宏。否则,GDB 使用当前位置范围的宏
同时,GDB 不支持##符号剪接操作符,#宏字符串常量替换操作符,或者可变长宏。
无论何时GDB计算表达式,总会将在表达式里引用的宏展开。GDB 也提供下列命令来明确地识别宏。
macro expand expression
macro exp expression
显示表达式里引用的所有预处理宏的展开结果。由于GDB只简单地展开宏,不会去解析结果,因此表达式不必是有效的;可以是包
含任意符号的的字符串。
macro expand-once expression
macro exp1 expression
(此命令尚未实现。)显示在表达式里引用的预处理宏的展开结果。表达式里的所引用的宏不会改变。这个命令可以更清楚的查
看一个特殊宏,而不会被更多的展开所迷惑。由于GDB只是简单展开宏,而不解析结果,表达式不必是有效的;可是是任意符号的
字符串。
info macro macro
显示名为macro的宏的定义,并显示这个定义是在代码的何处设立的。
macro define macro replacement-list
macro define macro(arglist) replacement-list
(此命令尚未实现。)为名为macro的宏引入一个定义,对其的引用将被给定的replacement-list所替换。此命令的第一中
形式定义了“对象式”的宏,不带参数;第二种形式定义了一个“函数式”的宏,用给定的arglist作为参数的。
用此命令引入的定义,其范围在GDB所计算的所有表达式中,知道用命令macro undef命令删除之,如下所述。此定义会覆盖调试程
序里所有名为macro的宏定义,并且也包括任何用户提供的定义。
macro undef macro
(此命令尚未实现。)删除所有用户提供的名为macro宏定义。此命令只影响用命令macro define所定义的宏。如前所述;不能删
除调试程序里的定义宏。
macro list
(此命令尚未实现。)列举所有用macro define命令定义的宏。
下面的例子展示了如何使用上述命令。首先,看一下源代码:
$ cat sample.c
#include <stdio.h>
#include “sample.h”
#define M 42
#define ADD(x) (M + x)
main ()
{
#define N 28
printf (“Hello, world!\n”);
#undef N
printf (“We’re so creative.\n”);
#define N 1729
printf (“Goodbye, world!\n”);
}
$ cat sample.h
#define Q <
$
现在,让我们用GNU C编译器GCC来编译此程序。我用在编译的时候指定’-gdwarf-2′和’-g3′参数来产生预处理宏的调试信息。
$ gcc -gdwarf-2 -g3 sample.c -o sample
$
接着,我们就可以启动GDB来调试此例子程序了:
$ gdb -nw sample
GNU gdb 2002-05-06-cvs
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, …
(gdb)
我们可以展开宏并检查其定义,甚至是在程序尚未运行时。GDB 使用当前代码位置来判断哪个宏的定义处于此范围之内:
(gdb) list main
3
4 #define M 42
5 #define ADD(x) (M + x)
6
7 main ()
8 {
9 #define N 28
10 printf (“Hello, world!\n”);
11 #undef N
12 printf (“We’re so creative.\n”);
(gdb) info macro ADD
Defined at /home/jimb/gdb/macros/play/sample.c:5
#define ADD(x) (M + x)
(gdb) info macro Q
Defined at /home/jimb/gdb/macros/play/sample.h:1
included at /home/jimb/gdb/macros/play/sample.c:2
#define Q <
(gdb) macro expand ADD(1)
expands to: (42 + 1)
(gdb) macro expand-once ADD(1)
expands to: once (M + 1)
(gdb)
注意,在上面的这个例子里,macro expand-once只把原文本引用的宏展开–ADD的引用–但不展开宏M,此宏由ADD所引用。
一旦程序运行起来后,在当前堆栈帧的源代码上,GDB使用有效的宏定义:
(gdb) break main
Breakpoint 1 at 0×8048370: file sample.c, line 10.
(gdb) run
Starting program: /home/jimb/gdb/macros/play/sample
Breakpoint 1, main () at sample.c:10
10 printf (“Hello, world!\n”);
(gdb)
在第10行,宏N的有效定义是在第9行:
(gdb) info macro N
Defined at /home/jimb/gdb/macros/play/sample.c:9
#define N 28
(gdb) macro expand N Q M
expands to: 28 < 42
(gdb) print N Q M
$1 = 1
(gdb)
如果我们单步执行到删除N的定义之后,并给其新的定义,GDB会在每个点上找到有效的定义(或者没有定义):
(gdb) next
Hello, world!
12 printf (“We’re so creative.\n”);
(gdb) info macro N
The symbol ‘N’ has no definition as a C/C++ preprocessor macro
at /home/jimb/gdb/macros/play/sample.c:12
(gdb) next
We’re so creative.
14 printf (“Goodbye, world!\n”);
(gdb) info macro N
Defined at /home/jimb/gdb/macros/play/sample.c:13
#define N 1729
(gdb) macro expand N Q M
expands to: 1729 < 42
(gdb) print N Q M
$2 = 0
(gdb)
gdb define查看一个宏(C预处理宏)
最新推荐文章于 2024-01-08 10:45:44 发布