Что делает" 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 почти содержит правильный ответ на вопрос. Тем не менее, он похоронен глубоко во множестве ложных утверждений-см. комментарии. Таким образом, я чувствовал себя обязанным написать этот ответ.