为什么 argc 的地址在每个 运行 的程序中都不同?

Why is the address of argc different at each run of program?

今天遇到了以下情况。我运行多次执行以下程序:

#include <stdio.h>
int main(int argc, char **argv) {
  printf("%p\n", &argc);
}

在带有 linux 和 gcc 编译器的 Intel i7 上,此程序在每个 运行:

处给出不同的输出
i7:~/tmp$ gcc t.c 
i7:~/tmp$ ./a.out 
0x7fffc127636c
i7:~/tmp$ ./a.out 
0x7fffdefed97c
i7:~/tmp$ ./a.out 
0x7fff7f32454c

我希望 linux、elf、gcc 或任何相关的开发人员会尝试确保在每次调用程序时堆栈都位于相同的地址。这将有助于跟踪和修复在处理指针和变量地址时可能发生的奇怪错误(类似于与物理地址相比,虚拟地址更适合修复错误)。

我想知道为什么每次调用程序时堆栈都映射到不同的地址?

这是出于安全原因,因此攻击者无法对变量、函数等的确切内存布局做出太多假设...

我鼓励您阅读有关“缓冲区溢出攻击”(可能的原因之一)和“ASLR”(地址 Space 布局随机化)的内容,这是一种可能的预防性部分策展。

所以编译器生成固定地址是这种情况,但是运行时会改变一些东西...

如果您想更改该行为,请参见 disable ASLR in Linux 示例。