如何在gdb中打印#define的值?

12

我正在使用gdb进行堆栈调试,尝试获取someInt的值,但是我的有限gdb知识无法做到。我需要使用gdb获取someInt的值,它仅在#define行20之外的一个位置中被引用。

#define someInt 0x11111111

void someFunc() {
   // ...
   int a = 0;
   if(a==someInt) {  //line 20
   //...
   }
}
在调用编译程序后,我尝试过 gdb break 20 然后再使用 gdb x\dw $someInt 命令,但是出现了 No symbol 'someInt' in current context 的错误。如果我尝试用 x/dw 0x11111111 命令,会显示 'Cannot access memory at address 0x11111111'。因为无法重新编译代码(参考如何在GDB中打印#define常量?),所以不知道如何在该地址处打印值。请问如何使用 gdb(可能需要使用 x)来打印 someInt 的值?

获取someInt的值...概念问题。someInt到底是什么? - Sourav Ghosh
someInt 是一个值,如果 'a' 与其匹配,则通过 if 语句给我模拟 shell 访问权限,以演示书中的概念。 - Kurt Wagner
所以,你可以看到定义,但你仍然想知道宏的值吗?还是你需要打印a的值? - dbrank0
给自己一个方便,确保你的宏都是大写的。这样,你就不太可能与变量混淆,而你似乎正在做的就是这样。宏用于预处理器进行排序,一旦编译,它们将不再存在。 - Elias Van Ootegem
2个回答

13

答案在这里:GCC -g vs -g3 GDB Flag: What is the Difference?

使用 -O0 -ggdb3 进行编译:

gcc -O0 -ggdb3 source.c

来自文档

-ggdblevel - 请求调试信息并使用level指定信息的详细程度。默认级别为2。

级别3包括额外信息,例如程序中存在的所有宏定义。当您使用-g3时,一些调试器支持宏扩展。

9               if(a == someInt)
(gdb) list
4
5       int main()
6       {
7               int a=0;
8
9               if(a == someInt)
10              {
11                      printf("!\n");
12              }
13      }
(gdb) p someInt
$1 = 1111

0

是的。宏通常被扩展并简单地用作文本替换。这就是为什么gdb报告,在您的代码中没有someInt

实际上,在预处理之后,您的代码看起来像

void someFunc() {
   // ...
   int a = 0;
   if(a==0x11111111) {  //line 20 //note the change
   //...
   }
}

所以,在你的二进制文件中,不存在someInt

提示:不要将someInt误认为是一个变量。希望这可以帮到你。


1
重新澄清问题;我正在寻找如何使用gdb(以及与x结合使用)打印出#define地址处的值,而不是修改代码。 - Kurt Wagner
@KurtWagner,你怎么确定#define地址的值是可访问的?你在干什么? - Sourav Ghosh
我正在跟随一本渗透测试书籍,以更好地理解人们如何进行堆栈/堆溢出和获取 shell 访问等操作。这是其中的一个问题,所以应该是可行的,只是我没有掌握这个关键 gdb 概念... - Kurt Wagner
1
@KurtWagner:类似对象的宏没有任何地址。这些在预处理阶段后就消失了。要么重新编译程序并使用GDB手册中的正确语法,要么从程序源代码(或反汇编,如果符号不可用)中推断出来。 - Grzegorz Szpetkowski
啊,好的,我在想,也许我应该在寄存器上使用gdb?在英特尔架构中,如果语句中有第一/第二个参数,它们会被放在哪里? - Kurt Wagner
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接