每次调试时变量的地址是否改变

Does variable's address change each time debugging

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

我使用的代码:

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

编译:gcc main.c -g

并且在我的 Ubuntu 中,GDB 控制台 3 次都给出相同的结果:

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
 = (char **) 0x7fffffffe060

但是,运行 编译(可调试)a.out 文件两次,它为 &p 提供不同的输出:

heap=0x1c47010 stack=0x7ffd2df09b50
heap=0x25a5010 stack=0x7ffd757125f0

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

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

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

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

set disable-randomization

set disable-randomization on

This option (enabled by default in GDB) will turn off the native randomization of the virtual address space of the started program. This option is useful for multiple debugging sessions to make the execution better reproducible and memory addresses reusable across debugging sessions.

set disable-randomization off

Leave the behavior of the started executable unchanged.