私はCでclone()
関数を使用しようとしていますが、2番目の引数がどのように機能するかは不明です。 clone()
manページあたり:this articleのコメントで提案に従った後Cでクローン関数を使用するのに、このポインタ演算が必要なのはなぜですか?
The child_stack argument specifies the location of the stack used by the
child process. Since the child and calling process may share memory, it
is not possible for the child process to execute in the same stack as the
calling process. The calling process must therefore set up memory space
for the child stack and pass a pointer to this space to clone(). Stacks
grow downwards on all processors that run Linux (except the HP PA proces‐
sors), so child_stack usually points to the topmost address of the memory
space set up for the child stack.
、私はこのCのプログラムを使用して作業を簡単な例を得ることができました:
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <assert.h>
#define SIZE 65536
int v1;
int run(void *arg) {
v1 = 42;
return 0;
}
int main(int argc, char **argv) {
void **child_stack;
int pid, rc, status;
v1 = 10;
child_stack = (void **) malloc(SIZE);
assert(child_stack != NULL);
printf("v1 before: %d\n", v1);
pid = clone(run, child_stack + SIZE/sizeof(void **), CLONE_VM, NULL);
//pid = clone(run, child_stack + SIZE, CLONE_VM, NULL);
assert(pid != -1);
status = 0;
rc = waitpid(pid, &status, __WALL);
assert(rc != -1);
assert(WEXITSTATUS(status) == 0);
printf("v1 after: %d\n", v1);
return 0;
}
をしかし、私は混乱していますなぜclone
行の中の特定のポインタ算術が必要であるかについて。与えられたclone
ドキュメントによると、スタックは下向きに成長するはずですが、私はなぜそれを渡す前にmalloc
によって返されたポインタに値を追加すべきかを知っています。しかし、私はあなたがバイト数を追加すると思いますmalloc ' dを、その値を8で割った値(64ビットシステム上)ではなく、実際に動作するように見えます。上記のコードは、私がSIZE
を定義したものとは関係なく正常に動作しているようですが、代わりにコメント付きのバージョンを使用すると、特定のしきい値を超えるすべてのSIZE値に対してセグメンテーション違反が発生します。
だから、与えられたclone
行はなぜ機能しますが、コメントされた行はなぜですか? hereを説明するように、私が代わりにfork
かのpthreadの、そもそもclone
を使用している理由については
は、私は、chroot監獄の抜け出しから信頼されていないプロセスを防ぐために、その高度なサンドボックス機能のいくつかを使用しようとしています。
'void **'ではなく 'void **'型の 'child_stack'はなぜですか? – SiegeX
これは必須ではありません(任意のポインタ型を使用できます)。これは元の作者が使用していたタイプなので、ここで続けました。あなたが別のコメントで指摘したように、 'char *'はこのテストケースにとってより簡単な型のようです(sizeof()の必要条件を避けるため)。 – DRH