问题描述
我有一个针对 net5 的顶级控制台应用程序,其中包含以下代码:
Work();
void Work()
{
Work();
}
它最终会抛出一个 StackOverflowException
并将最后一个已知的堆栈大小打印到控制台。以下是几次运行的结果:
32120
32113
32133
32127
当我以 .net framework 4.8 为目标时,我也看到了堆栈大小的这种可变性。
我查看了 ECMA-335 Standard: Common Language Infrastructure 并找到了关于 StackOverflowException
的这句话:“此异常的精确时间及其发生的条件是特定于实现的”。
然后我发现了 ASLR(地址空间布局随机化),并认为 CLI 实现可能使用了类似的技术。
我的问题是,为什么会存在这种可变性,如果 ASLR 关闭,潜在的攻击如何运作?
解决方法
如果该位置没有足够的空间来扩展堆栈,ASLR 可能会限制堆栈的大小。
不要对 StackOverflowException
的时间做任何假设。任何时候由于深度递归而存在命中它的风险,您都应该在堆上使用自定义 Stack
对象并将您的代码转换为迭代形式。