「自動スタック拡張」とは何ですか?

「自動スタック拡張」とは何ですか?

制限を受ける(2)マニュアルページには次の定義があります。

RLIMIT_AS プロセスの仮想メモリ(アドレス空間)の最大サイズ(バイト単位)。この制限はbrk(2)、mmap(2)、およびmremap(2)への呼び出しに影響し、この制限を超えるとENOMEMエラーで失敗します。返品自動スタック拡張失敗します(sigatstack(2)で利用可能な代替スタックがない場合、プロセスを終了するためにSIGSEGVが作成されます)。値が long なので、32 ビット long を使用するマシンでは、この制限が最大 2GiB か、このリソースが無制限です。

ここで「自動スタック拡張」とはどういう意味ですか? Linux / UNIX環境のスタックは必要に応じて増加しますか?それでは、具体的なメカニズムは何ですか?

ベストアンサー1

Linuxの正確なメカニズムは次のとおりです。匿名マッピングのページエラー処理あなた「増加する割り当て」であることを確認してください。スタックのように拡張する必要があります。 VMゾーン履歴にそれを行う必要があるとマークされている場合は、開始アドレスを調整してスタックを拡張できます。

ページ障害が発生した場合は、アドレスに基づいてスタック拡張を介して処理できます(エラーの削除も可能です)。すべてのユーザープログラムは、仮想メモリの「失敗時の成長」動作を要求し、システムコールMAP_GROWSDOWNにフラグを渡すことができます。mmap

ユーザープログラムでもこのメカニズムを使用できます。

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>

int main() {
        long page_size = sysconf(_SC_PAGE_SIZE);
        void *mem = mmap(NULL, page_size, PROT_READ|PROT_WRITE, MAP_GROWSDOWN|MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
        if (MAP_FAILED == mem) {
                perror("failed to create growsdown mapping");
                return EXIT_FAILURE;
        }

        volatile char *tos = (char *) mem + page_size;

        int i;
        for (i = 1; i < 10 * page_size; ++i)
                tos[-i] = 42;

        fprintf(stderr, "inspect mappping for originally page-sized %p in /proc... press any key to continue...\n", mem);
        (void) getchar();

        if (munmap(mem, page_size))
                perror("failed munmap");

        return EXIT_SUCCESS;
}

プロンプトが表示されたら、プログラムのpid(pass ps)を見つけて、元の/proc/$THAT_PID/maps領域がどのように大きくなるかを確認します。

おすすめ記事