実際にプロセスのすべてのエントリと終了をログに記録する場合は、カーネルにフックする必要があります。つまり、カーネルを変更するか、少なくともカーネルモジュールを書くことです。 "linux security modules"は確かに入り込むことができますが、私はそれが終了することが可能かどうかは分かりません。
一時的に終了することがあります(バイナリが静的にリンクされているか、何らかの理由で環境設定がされていない場合)。ライブラリを事前にロードするだけで簡単なオプションがあります。
Linuxダイナミックリンカには、環境変数LD_PRELOAD
(see this question)が共有ライブラリに名前を付けると、そのライブラリが強制的に起動プロセスにロードされるという特徴があります。したがって、ライブラリを作成することができます。これは静的初期化でデーモンにプロセスが開始されたことを伝え、プロセスが終了したときにプロセスがそのことを知るようにします。
スタティック初期化は、C++でコンストラクタを使用してグローバルオブジェクトを作成すると簡単に行えます。ダイナミックリンカは、ライブラリがロードされたときに静的コンストラクタが確実に実行されるようにします。
また、プロセスが終了したときに対応するデストラクタを実行しようとするので、コンストラクタとデストラクタにプロセスを単に記録することもできます。しかし、プロセスがシグナル9(KILL)で消滅し、他のシグナルが何をするのかわからない場合は動作しません。
代わりに、デーモンがあり、コンストラクタでデーモンにプロセスの開始を伝え、プロセスが自身のプロセスを終了するときに通知するようにしてください。 1つの選択肢は、デーモンへのunix-domainソケットを開いて開いておくことです。プロセスが終了し、デーモンが気付くと、カーネルはプロセスを終了します。いくつかのプロセスでは、低い記述子番号(3,4,5)が空いていると仮定し、dup2
と仮定している可能性があるので、ソケットに高い記述子番号を使用するためにいくつかの注意を払う必要があります。また、デーモンやシステム全体のファイル記述子を一般的に許可することを忘れないでください。
/procファイルシステムをポーリングするだけで、分割された状態でしか存在しない膨大な数のプロセスが見逃されることに注意してください。 UNIX上には本当に多くのものがあります。
おそらくカーネルモジュールを書く必要があります。私はあなたがユーザー空間からこれを正確に行うことはできないと思います。 –
関連:http://lists.kernelnewbies.org/pipermail/kernelnewbies/2011-September/003367.html –
ptrace(http://en.wikipedia.org/wiki/Ptrace)を使用すると、 gdbのようにsyscallsをトラップしてください。プログラムをrootとして実行する必要があります。私は**システム全体のためにそういったアプローチがいかに重くなるか分かりません。 –