gpt4 book ai didi

linux - 堆栈溢出是否总是导致段错误?

转载 作者:可可西里 更新时间:2023-11-01 11:51:13 26 4
gpt4 key购买 nike

在 Linux 中,当正在运行的程序试图使用超过限制(堆栈溢出)的堆栈空间时,通常会导致“段错误”错误并中止执行。

是否保证超过栈空间限制就一定会导致segmentation fault错误?或者程序是否会继续运行,可能由于数据已损坏而出现一些错误行为?

另一种表达方式:如果程序因产生错误结果但没有崩溃而行为不当,原因是否仍然是堆栈溢出?

编辑:澄清一下,这个问题不是关于“堆栈缓冲区溢出”,而是关于堆栈溢出,当程序使用的堆栈空间超过堆栈大小限制(Linux 中由 给出的限制) ulimit -s).

最佳答案

堆栈溢出变成访问冲突需要某种内存管理硬件。如果没有硬件辅助内存保护,过度生长的堆栈将与其他一些内存分配发生冲突,导致相互损坏。

在按需分页的虚拟内存操作系统上,堆栈的上限由保护页保护:保留(不会分配给任何东西)并标记的虚拟内存页“不存在”,因此访问它会产生违规行为。保护页只有那么多字节宽;堆栈指针仍然可能意外地在保护页上递增并落入一些不相关的可写内存(例如属于堆分配的映射),在那里将造成严重破坏,而不必触发任何内存访问冲突。

在 C 语言中,我们可以很容易地通过声明大型、未初始化的非static block 作用域数组,如 char array[8192];//(是 4096 字节保护页的两倍)。使用像 alloca 或 C99 可变长度数组这样的特性,我们可以动态地做到这一点:我们可以编写一个程序,读取一个整数值作为运行时输入,然后将堆栈递增那么多。

我多年前调试过一个问题,第三方代码有调试日志宏,在宏的扩展中有一个临时数组,如 char print_buf[8192] 用于格式化消息。这用于具有许多线程的多线程应用程序,其堆栈大小减少到仅 64 KB。多亏了这个 print_buf,一个线程溢出的堆栈直接越过了保护页,落在另一个线程的堆栈中,破坏了它的局部变量,导致众所周知的“欢闹接踵而至”。

关于linux - 堆栈溢出是否总是导致段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57794093/

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