Предел устанавливается немедленно, но проверяется только при попытке выделить новый стек или при попытке увеличить существующий стек.Grep для RLIMIT_STACK ( или поиск по идентификатору LXR ) в исходных текстах ядра должен указывать.
Очевидно, начальный размер стека - это то, что необходимо для имени файла + env strings + argстроки плюс некоторые дополнительные страницы, выделенные на setup_arg_pages
(20 страниц в 2.6.33 1 , 2 , 128 КБ на 2.6.34 3 ).
В итоге:
initial stack size = MIN(size for filename + arg strings + env strings + extra pages, MAX(size for filename + arg strings + env strings, RLIMIT_STACK))
где
size for filename + arg strings + env strings <= MAX(ARG_MAX(32 pages), RLIMIT_STACK/4)
Кроме того, ядра с патчем exec-shield
Инго Молнара (Fedora, Ubuntu, ...) имеют дополнительный EXEC_STACK_BIAS "(еще 2 МБ для покрытия эффектов рандомизации.)" , см. Вызов новой функции over_stack_limit()
из acct_stack_growth()
( [Ubuntu1] , [Ubuntu2] , [Ubuntu3] ).
Я отредактировал оригинальную программу, чтобы показать это:
#include <stdio.h>
#include <sys/resource.h>
void foo(void);
int main(int argc, char *argv[]) {
struct rlimit lim = {1, 1};
if (argc > 1 && argv[1][0] == '-' && argv[1][8]=='l') {
printf("limiting stack size\n");
if (setrlimit(RLIMIT_STACK, &lim) == -1) {
printf("rlimit failed\n");
return 1;
}
}
foo();
return 0;
}
void foo() {
unsigned ints[32768];
printf("foo: %u\n", ints[2047]=42);
}
В результате:
$./rl
foo: 42
$./rl -l
limiting stack size
Segmentation fault
$