gpt4 book ai didi

c - 当堆栈增长时,谁负责向操作系统请求页面?

转载 作者:行者123 更新时间:2023-12-02 18:21:10 27 4
gpt4 key购买 nike

我对此有点模糊 - 但我认为操作系统需要能够跟踪进程线程正在使用(或保留)虚拟地址空间中的哪些页面。对于程序员通过VirtualAlloc明确请求的内存(或您的操作系统等效项),这很简单。但是,当堆栈随着线程执行而增大/缩小时,堆栈会溢出不同数量的页面。显然,应用程序程序员没有请求使用这些页面 - 那么谁来处理对操作系统的请求? C 运行时?我不认为操作系统可以自动执行此操作。我缺乏汇编知识来转储可执行文件并检查自己..

最佳答案

Linux是开源的,你可以看看它是做什么的。这是来自arch/x86/mm/fault.c__do_page_fault函数处理(等待它)页面错误:

    vma = find_vma(mm, address);
if (unlikely(!vma)) {
bad_area(regs, error_code, address);
return;
}

if (likely(vma->vm_start <= address))
goto good_area;
if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) {
bad_area(regs, error_code, address);
return;
}
if (error_code & 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, error_code, address);
return;
}
}
if (unlikely(expand_stack(vma, address))) {
bad_area(regs, error_code, address);
return;
}

find_vma 查找在故障地址上方结束的第一个映射区域。如果故障位于起始地址之上,则这是对已映射内存的正常访问,因此此处无需执行任何操作(转到 good_area)。

否则,如果它不是一个可以向下生长的区域,我们就会出错。我们剩下的是一个可以向下生长的区域下方的 channel 。这是堆栈的常见情况。

接下来,代码检查错误和堆栈指针的关系。通常,局部变量是通过首先移动堆栈指针来分配的,但这不是内存访问,因此不会产生错误。堆栈将在第一次访问时扩展,因此应位于堆栈指针上方。注释 Accessing the stack below %sp is always a bug. 与此相关。然而,有些指令暂时访问堆栈指针下方,因此对此做了一些考虑。此外,一些 ABI 使用所谓的红色区域,它是堆栈指针下可自由使用的固定大小区域。您可以看到它认为堆栈指针大约 64kB 内的任何访问都是有效的访问。如果一切正常,堆栈实际上已扩展。

关于c - 当堆栈增长时,谁负责向操作系统请求页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27385759/

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