GNU/Linux >> Linux の 問題 >  >> Linux

Linuxでclone()システムコールのスタックをmmapする方法は?

mmap には MAP_ANONYMOUS フラグが必要です。 MAP_GROWSDOWN は、スタックとして使用したいためです。

次のようなもの:

void *stack = mmap(NULL,initial_stacksize,PROT_WRITE|PROT_READ,MAP_PRIVATE|MAP_GROWSDOWN|MAP_ANONYMOUS,-1,0);

詳細については、mmap の man ページを参照してください。そして、クローンは低レベルの概念であり、それが提供するものが本当に必要でない限り使用することを意図していないことを覚えておいてください.また、独自のスタックを設定するなど、多くの制御を提供します (関連するすべてのプロセスでスタックにアクセスできるようにするなど)。 clone を使用する非常に正当な理由がない限り、fork または pthread を使用してください。


スタックは、成長のためのスペースが無制限ではありません。他のすべてのものと同様に、それらはプロセスの仮想アドレス空間に存在し、拡大できる量は、隣接するマップされたメモリ領域までの距離によって常に制限されます。

動的に成長するスタックについて人々が話すとき、彼らが意味することは次の 2 つのいずれかです。

  • スタックのページは、最初の書き込みが実行されるまでプライベート コピーが作成されないコピー オン ライト ゼロ ページである可能性があります。
  • スタック領域の下位部分は、ガード ページがヒットするまで、まだ予約されていない可能性があります (したがって、プロセスのコミット チャージ、つまりカーネルがプロセス用に予約されている物理メモリ/スワップの量にカウントされません)。 、この場合、カーネルはさらにコミットしてガード ページを移動するか、コミットするメモリが残っていない場合はプロセスを強制終了します。

MAP_GROWSDOWN に頼ろうとしている フラグは信頼できず、危険です mmap から保護できないため スタックのすぐ隣に新しいマッピングを作成すると、それが上書きされます。 (http://lwn.net/Articles/294001/ を参照) メインスレッドの場合、カーネルはスタックサイズ ulimit を自動的に予約します。 アドレス空間の価値 (メモリではありません ) をスタックの下に置き、mmap を防ぎます それを割り当てることから。 (ただし、注意してください! ベンダーがパッチを適用した一部の壊れたカーネルでは、この動作が無効になり、ランダムなメモリ破損が発生します!) 他のスレッドについては、必ず mmap スタックを作成するときにスレッドがスタックに必要とする可能性のあるアドレス空間の全範囲。他に方法はありません。 できる 最初はほとんどを書き込み不可/読み取り不可にし、障害が発生した場合は変更しますが、シグナルハンドラーが必要になり、アプリケーションのシグナルハンドラーに干渉するため、このソリューションは POSIX スレッドの実装では受け入れられません。 (拡張機能として、カーネルは できる 特別な MAP_ を提供 SIGSEGV の代わりに別のシグナルを配信するフラグ マッピングへの不正なアクセスが発生すると、スレッドの実装がこのシグナルをキャッチして処理する可能性があります。しかし、現在の Linux にはそのような機能はありません。)

最後に、clone syscall はスタック ポインター引数を必要としないため、取りません。 syscall はアセンブリ コードから実行する必要があります。これは、ユーザー空間ラッパーが「子」スレッドのスタック ポインターを目的のスタックを指すように変更し、親のスタックに何も書き込まないようにする必要があるためです。

実は、clone ユーザー空間に戻った後に「子」のスタックポインターを変更するのを待つのは安全ではないため、スタックポインター引数を取ります。シグナルがすべてブロックされない限り、シグナル ハンドラーが間違ったスタックですぐに実行される可能性があり、一部のアーキテクチャでは、スタック ポインターが有効であり、常に安全に書き込みできる領域を指している必要があります。

C からスタック ポインターを変更することは不可能であるだけでなく、syscall の後、スタック ポインターが変更される前に、コンパイラーが親のスタックを上書きする可能性も回避できませんでした。


Linux
  1. Linux:デバイスに使用されているデバイスドライバーを見つける方法は?

  2. LinuxでMimeタイプのアプリケーションを見つける方法は?

  3. Linux 用 Windows サブシステムで X マウス ポインターのサイズを設定する方法

  1. Linuxシステムリカバリにsystemd-nspawnを使用する方法

  2. OSとLinuxのバージョンを確認する方法

  3. LinuxシステムのIDを変更する方法

  1. Linux –非特権ユーザーのシステムビープ音を無効にする方法は?

  2. アセンブリの Linux システム コール テーブルまたはチートシート

  3. パラメータをLinuxシステムコールに渡す方法は?