gpt4 book ai didi

c - Linux堆栈的动态扩展

转载 作者:太空狗 更新时间:2023-10-29 11:06:48 25 4
gpt4 key购买 nike

我注意到 Linux 堆栈开始时很小,然后随着递归/推送/vlas 导致的页面错误扩展到大小 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);
}
}

什么内核代码在做这个?它如何区分自然堆栈增长和我在地址空间中四处寻找?

最佳答案

linux内核以栈指针的内容为界限(在合理的范围内)。访问堆栈指针 减去 65536 和 32 unsigned longs 的大小会导致分段违规。因此,如果您访问堆栈中的内存,您必须确保堆栈指针以某种方式随着访问而减少,以使 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;
}
}

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

关于c - Linux堆栈的动态扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54564273/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com