制限はすぐに設定されますが、新しいスタックを割り当てようとするとき、または既存のスタックを拡張しようとするときにのみチェックされます。カーネル ソースの RLIMIT_STACK (または LXR 識別子検索) の grep でわかるはずです。
どうやら、スタックの初期サイズは、ファイル名 + env 文字列 + arg 文字列に加えて、割り当てられたいくつかの余分なページに必要なものですsetup_arg_pages
(2.6.33 1では20 ページ、 2.6.34では 128 Kb 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 "(ランダム化の影響をカバーするために 2MB 以上。)"があります。( [Ubuntu1]over_stack_limit()
、[Ubuntu2]、[ Ubuntu3] )。acct_stack_growth()
これを示すために元のプログラムを編集しました。
#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
$