为什么 MAP_GROWSDOWN 映射不增长? [英] Why is MAP_GROWSDOWN mapping does not grow?

查看:11
本文介绍了为什么 MAP_GROWSDOWN 映射不增长?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试创建 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
", 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;

因为:

返回地址比进程虚拟地址空间中实际创建的内存区域低一页.在映射下方的守卫"页面中触摸地址会导致映射增长按一页.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆