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

查看:85
本文介绍了为什么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\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屋!

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