
私はclone()のLinuxのmanページをよく読んでおり、clone()ラッパーと「raw」システムコールの違いを理解しています。しかし、私が理解していないのは、ラッパーでCLONE_VMが使用されていない場合でも、親プロセスが子プロセスにスタックを割り当てる必要がある理由です。
CLONE_VMを使用しない場合、ラッパーはスタック引数を無視しますか?それではなぜ必要なのでしょうか?元のシステムコールではnullが許可されていますが、これは意味がありますが、ラッパーにこれが必要な理由を理解できません。ラッパーが言わなくても、子と親がメモリを共有できるようにしますか?
答え1
必須スタックパラメータは次のとおりです。fn
議論。ネイティブカーネルシステムコールは次のように動作するため、常にスタックを必要としませんfork
。システムコールが返されると、子エントリの実行が開始されます。その後、libcラッパーは呼び出し内容を設定する必要がありますfn
。スタックが必要です(そしてこれはいつも行われてきました。)。
clone
したがって、システムコールを介して関数を呼び出すコードfn
(thread_start
glibcコード)に情報を渡すためにラッパーを呼び出すときは、常にスタックが必要です。
答え2
私は自分で答えを見つけたと信じています。レプリケーションラッパー(clone.s)のx86-64ソースファイルを見てみると、次のような興味深いコードが見つかりました。
movq %rdi,0(%rsi)
これにより、子プロセススタックに関数ポインタが配置されます。これはレプリケーションシステムコールの前に発生します。私が理解したことが正しい場合、子プロセスはラッパーに渡された関数に戻ります。これは、関数アドレスを入れることができるようにラッパーにスタックパラメータが必要な理由を示しています。これは、スタックが関数ポインタとパラメータを受け入れるのに十分な大きさでなければならないことを意味するようです。マニュアルページでは、なぜこれを説明していないのか、読んでいる間に何かを見逃したのかはわかりません。