Linux - 为什么程序中断指针 (brk/sbrk) 每次程序都是不同的 运行?
Linux - why is the program break pointer (brk/sbrk) different each time a program is run?
我了解到program break是LinuxOS为进程分配的最高虚拟内存地址,因此标记了堆的最高地址。您可以通过调用 sbrk( 0 ).
来获取程序中断的地址
当我创建以下简单程序时,每次 运行:
我都会得到不同的结果
#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 部分的正上方分配的 - 我想我期望它对于像这样的小程序总是具有相同的初始值。程序中断最初定位的位置是否有一些随机化或其他内容?如果不是,为什么我每次 运行 程序都不一样?
是的,有随机性。称为地址 Space 布局随机化 (ASLR)。 http://en.wikipedia.org/wiki/Address_space_layout_randomization
默认情况下,内核会随机化初始点,但可以禁用此功能。这是 运行 的代码(对于 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
}
我了解到program break是LinuxOS为进程分配的最高虚拟内存地址,因此标记了堆的最高地址。您可以通过调用 sbrk( 0 ).
来获取程序中断的地址当我创建以下简单程序时,每次 运行:
我都会得到不同的结果#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 部分的正上方分配的 - 我想我期望它对于像这样的小程序总是具有相同的初始值。程序中断最初定位的位置是否有一些随机化或其他内容?如果不是,为什么我每次 运行 程序都不一样?
是的,有随机性。称为地址 Space 布局随机化 (ASLR)。 http://en.wikipedia.org/wiki/Address_space_layout_randomization
默认情况下,内核会随机化初始点,但可以禁用此功能。这是 运行 的代码(对于 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
}