Ответ 1
Предел устанавливается сразу же, но проверяется только при попытке выделить новый стек или пытается увеличить существующий стек. Должен сказать grep для RLIMIT_STACK (или поиск идентификатора LXR) в источниках ядра.
По-видимому, начальный размер стека - это то, что необходимо для имени файла + env строки + строки arg плюс некоторые дополнительные страницы, выделенные на setup_arg_pages
(20 страниц в 2.6.33 1, 2, 128 Kb на 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)
Кроме того, ядра с патчем Ingo Molnar 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
$