gpt4 book ai didi

c++ - GCC -fstack-check 选项在 C 中引发了什么异常

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:36:13 24 4
gpt4 key购买 nike

根据 gcc 文档

-fstack-check

Generate code to verify that you do not go beyond the boundary of the stack. Note that this switch does not actually cause checking to be done; the operating system must do that. The switch causes generation of code to ensure that the operating system sees the stack being extended.

我的假设是这个额外的代码会产生异常让操作系统知道。使用 C 语言时,我需要知道额外代码生成了什么异常。

Google 也帮不上什么忙。关闭 我开始知道它在 Ada 语言 ( Reference ) 的情况下生成 Storage_Error 异常。

我正在开发一种小型操作系统/调度程序,我需要在其中捕获此异常。我正在使用 C/C++。

我的 GCC 版本 3.4.4

最佳答案

它不会直接产生任何异常。它生成代码,当堆栈扩大超过一页时,生成对新分配区域中每个页面的读写访问。这就是它所做的全部。示例:

extern void bar(char *);
void foo(void)
{
char buf[4096 * 8];
bar(buf);
}

编译(使用 gcc 4.9,在 x86-64 上,在 -O2)到:

foo:
pushq %rbp
movq $-32768, %r11
movq %rsp, %rbp
subq $4128, %rsp
addq %rsp, %r11
.LPSRL0:
cmpq %r11, %rsp
je .LPSRE0
subq $4096, %rsp
orq $0, (%rsp)
jmp .LPSRL0
.LPSRE0:
addq $4128, %rsp
leaq -32768(%rbp), %rdi
call bar
leave
ret

orq $0, (%rsp)(%rsp)处的内存内容没有影响,但CPU将其视为读写访问无论如何到那个地址。 (我不知道为什么 GCC 在循环期间将 %rsp 偏移 4128 字节,或者为什么它认为帧指针是必要的。)从理论上讲,如果堆栈变得太大,操作系统可以注意到这些访问并做一些适当的事情。对于符合 POSIX 标准的操作系统,这将是 SIGSEGV 信号的传递。

您可能想知道操作系统如何注意到这样的事情。硬件允许操作系统将地址空间的页面指定为完全不可访问;任何在这些页面中读取或写入内存的尝试都会触发硬件故障,操作系统可以按其认为合适的方式进行处理(同样,对于符合 POSIX 的操作系统,传送 SIGSEGV)。这可用于在为堆栈保留的空间末尾处立即放置一个“保护区”。这就是为什么每个页面一次访问就足够了。

明确地说,-fstack-check 旨在保护您免受“保护区”非常小的情况 - 可能只有一页 - 因此分配一个大缓冲区堆栈将堆栈指针通过该区域并移动到另一个可访问 RAM 区域。如果程序碰巧永远不会接触保护区内的内存,您不会立即崩溃,但您会在其他区域的任何地方涂鸦,从而导致延迟 Action 故障。

关于c++ - GCC -fstack-check 选项在 C 中引发了什么异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26370839/

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