Posix 中的守卫大小是多少?

Wil*_*oom 5 memory stack-overflow stack posix

这个问题的灵感来自pthread API 中的pthread_attr_setguardsize和方法。该方法的文档可以在此处pthread_attr_getguardsize找到。

在这些方法的文档中,我最接近地找到的有关防护大小实际大小的解释是:

Guardsize 属性控制所创建线程堆栈的保护区大小。Guardsize 属性提供防止堆栈指针溢出的保护。如果线程的堆栈是使用保护保护创建的,则实现会在堆栈的溢出端分配额外的内存,作为防止堆栈指针堆栈溢出的缓冲区。如果应用程序溢出到该缓冲区,则会导致错误(可能会向线程传递 SIGSEGV 信号)。

我确信这对某些人来说是完全有道理的,但我仍然有点迷失。

据我所知,守卫是位于堆栈末尾的溢出缓冲区,旨在防止堆栈溢出。不过我还有两个问题:

  1. 为什么使用特殊的溢出缓冲区比简单地使用更大的堆栈更好?
  2. 如果溢出防护仍然向线程发送错误,那么拥有溢出缓冲区还有什么意义呢?

我确信有一些简短的、概念性的东西可以回答这两个问题,我希望这里有人能够提供它。谢谢大家!

PS 这也非常有趣,我终于可以用“堆栈溢出”来标记问题了。

nos*_*nos 5

下一个问题是线程的堆栈之后会发生什么。

它可以是任何东西。它可能是另一个线程的堆栈顶部,是堆的一部分。一些内存映射文件等。

如果没有保护内存,线程可能会将其堆栈溢出到该区域,并且如果该内存是可写的,则没有任何东西可以阻止线程覆盖该内存,而不会生成任何错误/陷阱/信号。

您可以分配更大的堆栈。但多大才算足够大呢?如果分配太大,则意味着用于其他任何内容的可用内存会减少(特别是在内存空间非常有限的 32 位系统上)

保护区试图解决这个问题。该区域将被标记为不可写,因此,如果有人尝试写入该区域(即线程溢出其堆栈),则在硬件协助下,内核将收到通知,向进程发送信号并(默认情况下)终止它。

与冒着线程无声地损坏不应该损坏的内存的风险相比,终止进程通常要更好。