【发布时间】:2019-11-15 05:48:25
【问题描述】:
我尝试创建 MAP_GROWSDOWN 映射并期望它会自动增长。如手册页所述:
MAP_GROWSDOWN
此标志用于堆栈。它向内核虚拟内存系统指示映射应该向下扩展 记忆。返回地址比内存区域低一页 它实际上是在进程的虚拟地址空间中创建的。 触摸映射下方“守卫”页面中的地址会导致 按页面增长的映射。这种增长可以重复,直到 映射增长到下一个较低的高端的一页内 映射,此时触摸“保护”页面将导致
SIGSEGV信号。
所以我写了下面的例子来测试映射的增长:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/mman.h>
#include <stdio.h>
int main(void){
char *mapped_ptr = mmap(NULL, 4096,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_STACK | MAP_GROWSDOWN,
-1, 0);
if(mapped_ptr == MAP_FAILED){
int error_code = errno;
fprintf(stderr, "Cannot do MAP_FIXED mapping."
"Error code = %d, details = %s\n", error_code, strerror(error_code));
exit(EXIT_FAILURE);
}
volatile char *c_ptr_1 = mapped_ptr; //address returned by mmap
*c_ptr_1 = 'a'; //fine
volatile char *c_ptr_2 = mapped_ptr - 4095; //1 page below the guard
*c_ptr_2 = 'b'; //crashes with SEGV
}
所以我得到了SEGV,而不是增加映射。在这里成长是什么意思?
【问题讨论】:
-
mapped_ptr已经在保护页面中。在触摸它下面的页面之前先触摸它。 -
@ThomasJager 是的。我试图触摸
mapped_ptr。它被罚款了。但是,如果我在此之后触摸mapped_ptr - 4095,它无论如何都会出现段错误(我预计它会进一步增长)。 -
请添加包含!
-
嗯,我运行了代码,但无法正常工作。事实上,据我所知,MAP_GROWSDOWN 不再被任何东西使用,也不再用于堆栈,而且它并没有真正起作用,无论如何都应该被删除。它没有足够的保护。
-
@St.Antario 我只是将讨论链接起来,因为 Drepper 说 MAP_GROWSDOWN 无论如何都从根本上被破坏了。它也没有在我的机器上用于任何进程。
标签: c linux mmap segmentation-fault