在Linux堆的动态扩展

问题描述 投票:3回答:1

我已经注意到了Linux软件栈开始时很小,所造成的递归/推/沃拉斯高达尺寸getrlimit(RLIMIT_STACK,...),(我的系统默认为8MiB)给予或采取页面错误扩大。

奇怪的是,虽然,如果我直接寻址的字节,在限制范围内引起页面错误,Linux将只需定期段错误不扩大页面映射(无段错误不过,如果我做到这一点后,我不得不例如,ALLOCA,导致堆栈扩展)。

例如节目:

#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#define CMD "grep stack /proc/XXXXXXXXXXXXXXXX/maps"
#define CMDP "grep stack /proc/%ld/maps"
void vla(size_t Sz)
{
    char b[Sz];
    b[0]='y';
    b[1]='\0';
    puts(b);
}
#define OFFSET (sizeof(char)<<12)
int main(int C, char **V)
{
    char cmd[sizeof CMD]; sprintf(cmd,CMDP,(long)getpid());
    if(system(cmd)) return 1;
    for(int i=0; ; i++){
        printf("%d\n", i);
        char *ptr = (char*)(((uintptr_t)&ptr)-i*OFFSET);
        if(C>1) vla(i*OFFSET); //pass an argument to the executable to turn this on
        ptr[0] = 'x';
        ptr[1] = '\0';
        if(system(cmd)) return 1;
        puts(ptr);
    }
}

什么内核代码是干什么呢?它是如何自然堆积增长,我戳在地址空间周围的区分?

c linux memory page-fault
1个回答
3
投票

Linux内核需要堆栈指针作为极限的含量(合理边界内)。访问堆栈指针减去65536和大小为32米无符号长整型下面堆栈导致分段违例。所以,如果你访问存储在堆栈中向下,你必须确保,堆栈指针不知何故与访问降低为Linux内核放大段。看到/arch/x86/mm/fault.c这个片段:

if (sw_error_code & X86_PF_USER) {
    /*
     * Accessing the stack below %sp is always a bug.
     * The large cushion allows instructions like enter
     * and pusha to work. ("enter $65535, $31" pushes
     * 32 pointers and then decrements %sp by 65535.)
     */
    if (unlikely(address + 65536 + 32 * sizeof(unsigned long) < regs->sp)) {
        bad_area(regs, sw_error_code, address);
        return;
    }
}

堆栈指针寄存器的值在这里是关键!

© www.soinside.com 2019 - 2024. All rights reserved.