正确设置 ulimit 时出现分段错误 [英] Segmentation fault with ulimit set correctly

查看:36
本文介绍了正确设置 ulimit 时出现分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在 这个问题.

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

int main(){int a[510000];[509999] = 1;printf("%d", a[509999]);返回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) 的目的从来不是真正将事物微观管理到一个字节/微秒,它们只是为了阻止您的程序变得完全疯狂并用它来摧毁整个系统.不要将它们视为正确道路上的红灯和停车标志,将它们视为跑道上的跑​​道区域和防撞栏.

I tried to help an OP on this question.

I found out that a code like the one below causes segmentation fault randomly even if the stack is set to 2000 Kbytes.

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

As you can see the array is 510000 x 4 bytes = 2040000 bytes.

The stack is set to 2000 Kbytes (2048000 bytes) using ulimit command:

  • ulimit -s 2000
  • ulimit -Ss 2000

Based on those numbers the application has room to store the array, but randomly it return segmentation fault.

Any ideas?

解决方案

There's a few reasons why you can't do this. There are things that are already using parts of your stack.

main is not the first thing on your stack. There are functions called by the real entry point, dynamic linker, etc. that are before main and they are all probably using some of the stack.

Additionally, there can be things that are usually put on the top of the stack to set up execution. Many systems I know put all the strings in argv and all environment variables on top of the stack (which is why main is not the entry point, there's usually code that runs before main that sets up environment variables and argv for main).

And to top it off a part of the stack can be deliberately wasted to increase the randomness of ASLR if your system does that.

Run you program in the debugger, add a breakpoint at main, look up the value of the stack register and examine the memory above it (remember that most likely your stack grows down unless you're on a weird architecture). I bet you'll find lots of pointers and strings there. I just did this on a linux system and as I suspected all my environment variables were there.

The purpose of resource limits (ulimit) on Unix has never really been to micromanage things down to a byte/microsecond, they are there just to stop your program from going completely crazy and taking down the whole system with it. See them not as red lights and stop signs on a proper road, see them as run-off areas and crash barriers on a racetrack.

这篇关于正确设置 ulimit 时出现分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆