我是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是否可以保证任何变量在不同的调试时间都具有相同的地址,为什么?
还有,为什么只是运行而不是调试似乎使用了不同的方案?
答案 0 :(得分:10)
大多数Linux系统都启用了地址空间布局随机化(ASLR)。借助ASLR,每次都会在随机地址处加载地址空间的许多部分,包括可执行文件,堆和堆栈。这就是直接运行a.out
时看到的。
默认情况下,GDB禁用ASLR以使调试更加可预测。这是一个可配置的选项,可以打开或关闭。来自GDB manual:
设置禁用随机化
设置禁用随机化
此选项(在GDB中默认启用)将关闭已启动程序的虚拟地址空间的本地随机化。此选项对多个调试会话很有用,以使执行的重复性更好,并且在调试会话之间可重用内存地址。
关闭disable-randomization
保持启动的可执行文件的行为不变。