为什么内存地址在 Ubuntu 中发生变化而不是在 Redhat 中

why does memory address change in Ubuntu and not in Redhat

我有这个程序:

double t;
main() {
}

在 Ubuntu,我 运行:

% gdb a.out
(gdb) p &t
 = (double *) 0x4010 <t>
(gdb) run
Starting program: /home/phan/a.out 
[Inferior 1 (process 95930) exited normally]
(gdb) p &t
 = (double *) 0x555555558010 <t>

为什么地址从0x4010变成了0x555555558010。有什么办法可以防止这种情况发生吗? 在 Redhat 上,它不会这样做:

% gdb a.out
(gdb) p &t
 = (double *) 0x601038 <t>
(gdb) r
Starting program: /home/phan/a.out 
[Inferior 1 (process 23337) exited normally]
(gdb) p &t
 = (double *) 0x601038 <t>

顺便说一句,这只发生在 Ubuntu 18.04 中。在Ubuntu16.04中,和Redhat完全一样,即前后地址相同。

您可能会看到 .bss 段的前地址和 post-重定位地址。

您可以通过禁用与​​位置无关的可执行文件来避免这种情况,从而使 gcc 预先选择 .bss 寄存器的最终地址:

gcc -no-pie foo.c

-static会有效果。

我不知道为什么 Ubuntu 和 Redhat 之间会有区别。