2011-02-02 7 views
6

fork()システムコールがオーバーロードされ、RTLD_NEXTを使用してfork()という独自のバージョンを作成しました。つまり、dlsym(RTLD_NEXT, fork)です。これは私のフォークバージョンに当たるでしょう。この後、私は実際のfork()システムコールのタスクを再現したい、つまり、子プロセスを作成してpidを返すことと、さらにいくつかの追加機能を作りたいと思います。fork()のオーバーロード

私はそれを行う方法を理解することができません。 fork()(fork.c)のカーネルソースコードを調べたところ、それほど分かりませんでした。

は、これを行う:

dlsym(RTLD_NEXT,fork); 
int fork(void) { 
    int pid=_fork(); // Trying to call actual fork does not work 
    return pid; 
} 

はどのように私はそれを行うことができますか? (コメントから引き込ま)http://lxr.linux.no/linux+v2.6.32/kernel/fork.c#L10

編集:ここではフォークのソースコードをカーネルにリンクされ

私はツールを検出漏れに取り組んでいますが、このツールは、二重解放時に子プロセスを検出し、親によって割り当てられたメモリを削除します。これを克服するために、fork()をオーバーライドし、fork()があるときは常に、親のメモリ割り当てテーブルが子に複製されます。

+0

「動作しない」とはどういう意味ですか?ランタイムエラー?コンパイラエラー? – Simone

+0

@Simone:_fork(); //エラー:_forkが宣言されていません。私の考えは、フォークの実際のカーネルバージョンにヒットさせ、私のものではないようにすることでした。今はっきりしていることを願っています。 – kingsmasher1

+0

これを行うことで、正確に何を達成したいですか?あなたの最終目標は何ですか? – Omnifarious

答えて

3

syscall(SYS_fork)fork<sys/syscall.h>の後に呼び出すことができます。 syscall(2)を参照してください。

+0

本当に 'fork'システムコールがあったのかどうかは確かではありませんでした。私はそれが特定のパラメータセットを持つ 'クローン'コールに変換されたと考えました。 – Omnifarious

+0

@larsmans:それは良いアイデアを与える!!すばらしいです。私は今それを試して、それが動作するかどうかを見てみましょう。 – kingsmasher1

+0

@Omnifarious:それでも動作します。下向きの互換性、私は推測する。 –

7

カーネルソースコードforkから何か役に立つものは得られません。あなたのコードは、あなたが管理しているライブラリの細かいことに関係なく、カーネルが行うことを許可されません。これは、カーネルモジュールを作成せずに破ることができない厳しい境界です。

forkのライブラリコードはすべて設定されており、カーネルのforkコードが実行されるカーネルモードに切り替わる特別な命令を実行します。この特別な命令を自分のコードに入れる方法があります。それはsyscallの機能です。 forkには引数がないので、この関数を使ってシステムコールを行うのは比較的簡単です。

しかし、これは私がお勧めするものではありません。あなたがライブラリ牛車を共有何でも、基本的に

typedef int (*forkfunc_t)(void); 

int fork(void) 
{ 
    forkfunc_t sysfork = (forkfunc_t)dlsym(RTLD_DEFAULT, "fork"); 
    return sysfork(); 
} 

あなた自身でそれを交換する前に、あなたは基本的にfork機能の以前の値を取得するいくつかの方法を見つける必要があります:私はあなたの代わりにこれを行うお勧めします。

+0

私はリーク検出ツールで作業しています。このツールは、子プロセスが親によって割り当てられたメモリを削除すると、double freeを検出します。これを克服するために、私はfork()をオーバーライドし、fork()があるたびに、親のメモリ割り当てテーブルが子に複製されます。 – kingsmasher1

+0

@ kingsmasher1:ああ、カーネルが 'fork'を使って何をしているのかを変更する必要はないので、あなたがそれを傍受して適切にラップするだけです。これは非常に実践的なことです。共有ライブラリの手法はそれほど悪くはありません。 – Omnifarious

+0

@ kingsmasher1非常に重要な情報ですので、あなたの質問にあなたのコメントを編集しました!あなたがそれに満足していない場合は、それを編集してください。 –

0

とにかく、ひどくハッキングされているのでspoonはあなたが達成したいことを行い、その後関数であり、なぜ単にマクロ

#define fork() (spoon(),fork()) 

または

#define fork() spoon(fork()) 

を使用していません。

プリプロセッサは再帰を行わないことが保証されており、エクスプロレーション内にはforkのままです。

+0

私の問題fork()をオーバーロードする方法ではありませんでした。私は "dlsym" sys呼び出しを使用してそれをオーバーロードすることができました。私の問題はfork()の作業をどのように再現するかということでしたが、とにかくlarsmanの提案を使用して解決できるようになり、問題は解決しました。とにかくThatnks。 – kingsmasher1