Что делает" ulimit-s unlimited"?
понятно, что есть много связанных вопросов о распределении стека
что и где находятся стек и куча?
почему существует ограничение на размер стека?
однако на различных машинах *nix я могу выдать команду bash
ulimit -s unlimited
или команда csh
set stacksize unlimited
Как это меняет способ выполнения программ? Быть там любое влияние на производительность программы или системы (например, почему это не будет по умолчанию)?
в случае, если более подробные сведения о системе актуальны, я в основном связан с программами, скомпилированными с GCC на Linux, работающими на оборудовании x86_64.
3 ответов
одной из наиболее распространенных ошибок в стеке является чрезмерная или бесконечная рекурсия. Поскольку каждый новый вызов функции приводит к тому, что все ее переменные помещаются в стек, рекурсивные программы, оптимизированные без хвоста, могут быстро истощить пространство стека, выделенное процессу ядром. Например, эта бесконечно рекурсивная функция приведет к сбой ядра после превышения выделенного пространства стека:
int smash_the_stack(int number) {
smash_the_stack(number + 1);
return 0;
}
исчерпание пространства стека традиционно очень страшно, так как его можно использовать в чем-то, что называется "разбиение стека" или переполнение буфера стека. Это происходит, когда злонамеренный пользователь намеренно вызывает переполнение стека для изменения указателя стека для выполнения произвольных собственных инструкций вместо инструкций в собственном коде.
что касается производительности, не должно быть никакого влияния Любой. Если вы достигаете предела стека с помощью рекурсии, увеличение размера стека, вероятно, не лучшее решение, но в противном случае вам не о чем беспокоиться. Если программа абсолютно должна хранить огромные объемы данных, она может использовать кучу вместо этого.
Mea culpa, размер стека can действительно быть неограниченным. _STK_LIM
- это по умолчанию, _STK_LIM_MAX
- это то, что отличается от архитектуры, как видно из include/asm-generic/resource.h
:
/*
* RLIMIT_STACK default maximum - some architectures override it:
*/
#ifndef _STK_LIM_MAX
# define _STK_LIM_MAX RLIM_INFINITY
#endif
как видно из этого примера, общее значение бесконечно, где RLIM_INFINITY
, опять же, в общем случае определяется как:
/*
* SuS says limits have to be unsigned.
* Which makes a ton more sense anyway.
*
* Some architectures override this (for compatibility reasons):
*/
#ifndef RLIM_INFINITY
# define RLIM_INFINITY (~0UL)
#endif
поэтому я думаю, что реальный ответ - размер стека может быть ограничен некоторой архитектурой, тогда неограниченная трассировка стека будет означать все, что угодно _STK_LIM_MAX
определяется, и если это бесконечность-она бесконечна. Для подробностей о том, что значит установить его в бесконечность и какие последствия это может иметь, обратитесь к другому ответу, это намного лучше, чем мой.
"ulimit-s unlimited" позволяет стеку расти неограниченно. Это может предотвратить сбой вашей программы, если вы пишете программы рекурсией, особенно если ваши программы не являются хвостовыми рекурсивными (компиляторы могут "оптимизировать" их), а глубина рекурсии велика.
ответ @Maxwell Hansen почти содержит правильный ответ на вопрос. Тем не менее, он похоронен глубоко во множестве ложных утверждений-см. комментарии. Таким образом, я чувствовал себя обязанным написать этот ответ.