【发布时间】:2018-02-25 05:59:17
【问题描述】:
分段堆栈如何工作?这个问题也适用于Boost.Coroutine,所以我在这里也使用了 C++ 标签。主要的疑问来自这个article 看起来他们所做的是在堆栈底部保留一些空间,并通过向那里分配的内存注册某种信号处理程序来检查它是否已损坏(也许通过mmap和mprotect?) 然后,当他们检测到空间不足时,他们会继续分配更多内存,然后从那里继续。关于这个的3个问题
-
这不是用户空间的构造吗?他们如何控制新堆栈的分配位置以及如何编译程序指令以了解这一点?
push 指令基本上只是将一个值添加到堆栈指针,然后将值存储在堆栈上的一个寄存器中,那么 push 指令如何知道新堆栈的开始位置以及相应的 pop 如何知道何时它必须将堆栈指针移回旧堆栈?
-
他们也说
在我们得到一个新的堆栈段后,我们通过重试导致我们用完堆栈的函数来重新启动
goroutine这是什么意思?他们会重新启动整个 goroutine 吗?这不会导致不确定的行为吗?
他们如何检测到程序溢出堆栈?如果他们在底部保留一个金丝雀式的内存区域,那么当用户程序创建一个足够大的数组溢出时会发生什么?这不会导致堆栈溢出并且是一个潜在的安全漏洞吗?
如果 Go 和 Boost 的实现不同,我很高兴知道它们中的任何一个如何处理这种情况 ????
【问题讨论】:
-
Go 在 1.3 版本中开始使用连续栈
-
@tkausl 嗯.. 只需阅读它,这似乎肯定需要语言本身的支持,并且很难实现为像 Boost.Coroutine 这样的库。正确的?不过,连续堆栈方法似乎更容易理解
-
@Curious:是的,它需要语言支持——Go 的堆栈布局和调用约定与 C/C++ 不同。
标签: c++ go goroutine fiber boost-coroutine