很抱歉,如果这个问题措辞不当,但这是一个奇怪的问题,我不确定如何解释它。我写了一些涉及宏的愚蠢代码有一个愚蠢的错误,但即使我解决了这个问题,gdb也没有多大帮助。我认为问题可能在于我如何编写宏(它不是),所以我使用了-E标志,所以我可以检查代码并在没有宏的情况下调试它。然后发生了这件事:
/media/sf_Mint-Shared/C $ clang switch.c -E > switch_e.c
/media/sf_Mint-Shared/C $ clang switch_e.c -g -O0 -o switch
/media/sf_Mint-Shared/C $ gdb switch
[剪断]
(gdb) run
Starting program: /media/sf_Mint-Shared/C/switch
Enter your favorite fruit: apple
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b6f2f2 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) l
6 #define SWITCH(t) strcpy(switch_str, t);
7 #define CASE(c, d) if (!strcmp(switch_str, (c))) {d} else
8 #define ELSE(d) {d}
9 #define ENDSWITCH() switch_str = NULL;
10
11 int main()
12 {
13 char fruit[20];
14
15 printf("Enter your favorite fruit: ");
(gdb) l 26
21 scanf("%s", fruit);
22 to_lower(fruit);
23
24 SWITCH(0, fruit)
25 CASE(0, "apple", puts("Apples are delicious!");)
26 CASE(0, "pear", puts("Pears are alright");)
27 CASE(0, "banana", puts("Ew, bananas are gross");)
28 ELSE(puts("Sorry, I don't know that fruit.");)
29 ENDSWITCH(0)
30
如果不明显,尽管我从完全预处理的源编译了可执行文件,但宏仍然存在。这是进入处理器的(截断的)代码:
// Includes truncated
static char *switch_str;
int main()
{
char fruit[20];
printf("Enter your favorite fruit: ");
scanf("%s", fruit);
strcpy(switch_str, fruit);
if (!strcmp(switch_str, ("apple"))) {puts("Apples are delicious!");} else
if (!strcmp(switch_str, ("pear"))) {puts("Pears are alright");} else
if (!strcmp(switch_str, ("banana"))) {puts("Ew, bananas are gross");} else
{puts("Sorry, I don't know that fruit.");}
switch_str = ((void *)0);
return 0;
}
即使在预处理之后,原始宏如何保持不变?如何使用它们进行调试?
答案 0 :(得分:3)
gcc预处理器插入#line
指令,以便能够将预处理的行与原始行相关联。 gcc编译器使用这些指令来生成错误消息和调试信息。因此,即使您手动运行预处理器,也会指示gdb查看原始文件以获取源信息。
您可以使用c -P
选项来禁止#line
指令。