使用gdb的p &var命令获取变量地址与程序运行结果不一致的原因
问题:直接运行程序与GDB调试时变量地址不一致的原因?
我编写了如下简单C程序:
int x = 0; void main() { int y = 1; printf("x: %d\n", x); printf("y: %d\n", y); printf("&x: %p\n", (void*) &x); printf("&y: %p\n", (void*) &y); }
使用gcc -g simple.c编译后,直接运行./simple得到输出:
&x: 0x557123835014 &y: 0x7ffcad2a35f4
但通过gdb调试时,执行以下步骤:
gdb ./simple (gdb) b main (gdb) run (gdb) step (gdb) step (gdb) p &x $4 = (int *) 0x555555558014 <x> (gdb) p&y $5 = (int *) 0x7fffffffde14
获取的变量地址与直接运行结果不同,想询问导致该差异的原因。
原因解析
这种地址差异核心是**地址空间布局随机化(ASLR)**机制的影响,结合GDB的调试特性,具体分为两点:
全局变量地址差异:全局变量
x存在程序的全局存储区,现代操作系统默认开启ASLR,每次启动程序时会随机化程序的加载基地址。直接运行和通过GDB启动属于两次独立的程序加载过程,基地址随机值不同,因此全局变量的地址自然不一样。局部变量地址差异:局部变量
y存储在栈内存中,栈的起始地址同样受ASLR随机化影响。此外,GDB在调试时会为程序添加额外的调试栈帧信息,进一步改变了栈的布局,导致栈上变量的地址和直接运行时出现差异。
如果要验证这个结论,可以临时关闭ASLR:执行echo 0 | sudo tee /proc/sys/kernel/randomize_va_space,之后再分别直接运行程序和用GDB调试,变量地址就会保持一致。
内容的提问来源于stack exchange,提问作者DeadCat
相关产品推荐
相关产品推荐

