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

Hax*_*raZ 9 c debugging gdb

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

我正在使用的代码:

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

编译: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
$1 = (char **) 0x7fffffffe060
Run Code Online (Sandbox Code Playgroud)

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

heap=0x1c47010 stack=0x7ffd2df09b50
heap=0x25a5010 stack=0x7ffd757125f0
Run Code Online (Sandbox Code Playgroud)

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

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

kay*_*lum 10

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

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

设置禁用随机化

设置禁用随机化

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

设置禁用随机化关闭

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