目的:ゾンビプロセスまたは廃止されたプロセスの作成方法と、プロセステーブルからそれらを削除する方法を分析します。
ゾンビプロセスまたは廃止されたプロセスは、実行を完了したが、プロセステーブルにエントリがあるプロセスです。 これは、fork()
システムコールを使用して親プロセスによってforkされたが、wait()
システムコールを使用して親プロセスによってreapedされなかった子プロセスに発生
親プロセスは、子プロセスが終了した後、子プロセスの終了ステータスを取得するためにwait()
(またはwaitpid()
)システムコールを実行する必要があります。
親プロセスは、wait()
(またはwaitpid()
)システムコールを実行する必要があります。 wait()
呼び出しが親プロセスによって実行されない場合、子プロセスはゾンビプロセスになります。
子プロセスが終了するたびにSIGCHLD
シグナルが親プロセスに送信されます。 親プロセスはwait()
の呼び出しで定義されたSIGCHLD
シグナルハンドラ関数を持っている必要があります–これはプロセステーブルから子プロセスを削除します。
システムからゾンビプロセスを削除するには、SIGCHLD
シグナルをkill
コマンドを使用して手動で親に送信することができます。 親プロセスがまだゾンビプロセスを刈り取ることを拒否し、親プロセスを強制終了できる場合、次のステップは親プロセスを強制終了することです。 子プロセスが親プロセスを失うと、init
(PID1)が新しい親プロセスになります。 init
はwait()
システムコールを定期的に実行し、init
を親として持つゾンビプロセスを刈り取る。
私はゾンビプロセスを作成するための簡単なCプログラムを書いた。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#<stdioをインクルードします。h>
#<stdlibをインクルードします。h>
#<sys/typesをインクルードします。h>
#include<sys/wait.h>
#<unistdを含みます。h>
#<errnoをインクルードします。h>
intメイン()
{
pid_t child_pid;
int child_status;
child_pid=fork();
if(child_pid)> 0) {
// 親プロセスは30秒間スリープ状態になり、wait()
fprintf(stderr,”parent process-%d\n”,getpidを呼び出さずに終了します());
睡眠(30);
出口(0);
}
それ以外の場合(child_pid== 0) {
// 子プロセスはすぐに終了します
fprintf(stderr,”子プロセス-%d\n”,getpid());
出口(0);
}
それ以外の場合(child_pid== -1) {
// fork()エラー
perror(“fork()呼び出しに失敗しました”);
exit(-1);
}
else{
//これは起こらないはずです
fprintf(stderr,”fork()呼び出しからの%dの戻り値が不明”,child_pid);
exit(-2);
}
戻る0;
}
|
上記のコードをzombie.c
として保存し、gcc
を使用してコンパイルします。
$ gcc zombie.c -o zombie
次に、プログラムを実行します。
$ ./zombie parent process - 26570child process - 26571
別の端末から、実行中のプロセスを表示するにはps
を実行します。 あなたはゾンビプロセスが表示されます。
$ ps -ef | grep zombieibrahim 26570 22886 0 15:59 pts/2 00:00:00 ./zombieibrahim 26571 26570 0 15:59 pts/2 00:00:00 <defunct>
親プロセスが(30秒後に)終了すると、ゾンビプロセスはinit
プロセスによってプロセステーブルから削除されます。
モハメド-イブラヒム
ibrahim={interested_in(unix,linux,android,open_source,reverse_engineering);coding(c,shell,php,python,java,javascript,nodejs,react);plays_on(xbox,ps4);linux_desktop_user(true);}