每次调试时变量的地址都会改变吗

时间:2020-04-29 11:31:59

标签: c debugging gdb

我是GDB的新手,并且很好奇在不同的调试过程中可变地址是否会更改?

我正在使用的代码:

#include <stdio.h>
int main()
{
   char * p = malloc(10);
   printf("heap=%p stack=%p\n", p, &p);
}

编译:{{1​​}}

在我的Ubuntu中,GDB控制台出现了3次相同的结果:

gcc main.c -g

但是,两次运行已编译(可调试)的gdb$ b 5 Breakpoint 1 at 0x4005fb: file main4.c, line 5. gdb$ r Starting program: /home/zz/work/bold/src/a.out Breakpoint 1, main () at main4.c:5 gdb$ p &p $1 = (char **) 0x7fffffffe060 文件,它会为a.out提供不同的输出:

&p

GDB是否可以保证任何变量在不同的调试时间都具有相同的地址,为什么?

还有,为什么只是运行而不是调试似乎使用了不同的方案?

1 个答案:

答案 0 :(得分:10)

大多数Linux系统都启用了地址空间布局随机化(ASLR)。借助ASLR,每次都会在随机地址处加载地址空间的许多部分,包括可执行文件,堆和堆栈。这就是直接运行a.out时看到的。

默认情况下,GDB禁用ASLR以使调试更加可预测。这是一个可配置的选项,可以打开或关闭。来自GDB manual

设置禁用随机化

设置禁用随机化

此选项(在GDB中默认启用)将关闭已启动程序的虚拟地址空间的本地随机化。此选项对多个调试会话很有用,以使执行的重复性更好,并且在调试会话之间可重用内存地址。

关闭disable-randomization

保持启动的可执行文件的行为不变。