为什么MAP_GROWSDOWN映射不增长? [英] Why is MAP_GROWSDOWN mapping does not grow?
问题描述
我试图创建MAP_GROWSDOWN
映射,期望它会自动增长.如手册页中所述:
I tried to create MAP_GROWSDOWN
mapping with the expectation it would grow automatically. As specified in the manual page:
MAP_GROWSDOWN
MAP_GROWSDOWN
此标志用于堆栈.它向内核虚拟内存系统指示该映射应向下扩展
记忆.返回地址比存储区域低一页
实际上是在进程的虚拟地址空间中创建的.
触摸映射下方的防护"页面中的地址将导致
要按页面增长的映射.可以重复这种增长,直到
映射增长到下一个较低的高端的页面内
映射,此时触摸后卫"页面将导致
SIGSEGV
信号.
This flag is used for stacks. It indicates to the kernel virtual memory system that the mapping should extend downward in
memory. The return address is one page lower than the memory area
that is actually created in the process's virtual address space.
Touching an address in the "guard" page below the mapping will cause
the mapping to grow by a page. This growth can be repeated until the
mapping grows to within a page of the high end of the next lower
mapping, at which point touching the "guard" page will result in a
SIGSEGV
signal.
因此,我编写了以下示例来测试映射的增长:
So I wrote the following example to test the mapping growing:
#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
而不是扩大映射.在这里生长意味着什么?
So I got SEGV
instead of growing the mapping. What does it mean by growing here?
推荐答案
替换:
volatile char *c_ptr_1 = mapped_ptr - 4096; //1 page below
使用
volatile char *c_ptr_1 = mapped_ptr;
因为:
返回地址比在进程的虚拟地址空间中实际创建的内存区域低一页.触摸映射下方的"guard"页面中的地址将导致映射增大按一页.
The return address is one page lower than the memory area that is actually created in the process's virtual address space. Touching an address in the "guard" page below the mapping will cause the mapping to grow by a page.
请注意,我已经测试了该解决方案,并且可以在内核4.15.0-45-generic上按预期工作.
Note that I tested the solution and it works as expected on kernel 4.15.0-45-generic.
这篇关于为什么MAP_GROWSDOWN映射不增长?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!