我试图帮助this question上的OP。

我发现,即使堆栈设置为2000 KB,下面的代码也会随机导致分段错误。

int main ()
{
   int a[510000];
   a[509999] = 1;
   printf("%d", a[509999]);
   return 0;
}


如您所见,数组是510000 x 4个字节= 2040000个字节。

使用ulimit命令将堆栈设置为2000 KB(2048000字节):


ulimit -s 2000
ulimit -SS 2000


根据这些数字,应用程序有空间存储阵列,但随机返回分段错误。

有任何想法吗?

最佳答案

有几个原因导致您无法执行此操作。有些东西已经在使用堆栈的某些部分。

main不是堆栈上的第一件事。实际入口点,动态链接器等调用的函数在main之前,它们可能都使用了某些堆栈。

此外,通常可以将某些东西放在堆栈的顶部以设置执行。我知道许多系统都将所有字符串放在argv中,而所有环境变量都放在堆栈顶部(这就是为什么main不是入口点的原因,通常在main之前运行的代码会为main设置环境变量和argv)。

而且,如果您的系统这样做,可能会故意浪费堆栈的一部分来增加ASLR的随机性。

在调试器中运行程序,在main处添加一个断点,查找堆栈寄存器的值并检查其上方的内存(请记住,除非您使用的是奇怪的体系结构,否则堆栈很可能会变薄)。我敢打赌,您会在其中找到许多指针和字符串。我只是在Linux系统上执行此操作,因为我怀疑所有环境变量都在那儿。

Unix上的资源限制(ulimit)的目的从来没有真正地将事情管理到一个字节/微秒,它们只是在阻止您的程序完全发疯并破坏整个系统。请不要将它们视为红灯并在适当的道路上停车,而应将它们视为跑道上的径流区域和防撞栏。

关于c - 正确设置了ulimit的段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31293068/

10-12 05:44