Eli*_*ias 5 linux stack-overflow runtime-error segmentation-fault
在 Linux 中,当正在运行的程序尝试使用超过限制的堆栈空间(堆栈溢出)时,通常会导致“分段错误”错误并中止执行。
是否保证超出堆栈空间限制总是会导致分段错误错误?或者程序是否会继续运行,但可能由于数据损坏而出现一些错误行为?
另一种说法是:如果一个程序行为不当,产生了错误的结果,但没有崩溃,那么原因仍然是堆栈溢出吗?
编辑:澄清一下,这个问题不是关于“堆栈缓冲区溢出”,而是关于堆栈溢出,当程序使用的堆栈空间超过堆栈大小限制(Linux 中由 给出的限制ulimit -s)时。
堆栈溢出变成访问冲突需要某种内存管理硬件。如果没有硬件辅助的内存保护,过度增长的堆栈将与其他一些内存分配发生冲突,从而导致相互损坏。
在按需分页虚拟内存操作系统上,堆栈的上限受到保护页的保护:保留的虚拟内存页(不会分配给任何东西)并标记为“不存在”,以便访问它会生成违反。保护页只有这么多字节宽;堆栈指针仍然可能意外地在保护页上递增并落在一些不相关的可写内存中(例如属于堆分配的映射),在这些内存中将造成严重破坏,而不必触发任何内存访问冲突。
在 C 语言中,我们可以通过声明大型的、未初始化的非static块范围数组(例如char array[8192]; // (twice as large as a 4096 byte guard page). 使用allocaC99 可变长度数组等功能,我们可以动态地做到这一点:我们可以编写一个程序,读取一个整数值作为运行时输入,并将堆栈增加相应的量。
许多年前,我调试了一个问题,第三方代码具有调试日志记录宏,其扩展内部有一个临时数组,char print_buf[8192]用于格式化消息。这被用在具有许多线程的多线程应用程序中,其堆栈大小减少到仅 64 KB。由于这一点print_buf,一个线程的溢出堆栈直接跳过了保护页,并落在另一个线程的堆栈中,破坏了其局部变量,导致众所周知的“欢闹随之而来”。
| 归档时间: |
|
| 查看次数: |
535 次 |
| 最近记录: |