我知道程序中断是Linux操作系统为进程分配的最高虚拟内存地址,因此标志着堆的最高地址。 您可以通过调用sbrk(0)来获得程序中断的地址。
当我创build下面的小程序时,每次运行时都会得到不同的结果:
#define _BSD_SOURCE #include <stdio.h> #include <unistd.h> int main() { printf( "system break: %p\n", sbrk( 0 ) ); return 0; }
例如,在我的电脑上:
$ ./sbrk system break: 0x81fc000 $ ./sbrk system break: 0x9bce000 $ ./sbrk system break: 0x97a6000
我的理解是,堆是立即分配在虚拟内存中的BSS部分之上 – 我想我期望它会总是有一个像这样的小程序相同的初始值。 是否有一些随机或什么地方的节目中断最初定位? 如果不是,每次运行程序时为什么会有所不同?
默认情况下,内核将随机初始点,尽管可以禁用此功能。 这是运行的代码(对于x86,在arch / x86 / kernel / process.c中):
unsigned long arch_randomize_brk(struct mm_struct *mm) { unsigned long range_end = mm->brk + 0x02000000; return randomize_range(mm->brk, range_end, 0) ? : mm->brk; }
另外,在ELF二进制加载器(fs / binfmt_elf.c)的这个函数中,你可以看到这个函数:
if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) { current->mm->brk = current->mm->start_brk = arch_randomize_brk(current->mm); #ifdef CONFIG_COMPAT_BRK current->brk_randomized = 1; #endif }
是的,是随机的。 被称为地址空间布局随机化(ASLR)。 http://en.wikipedia.org/wiki/Address_space_layout_randomization