Unix / Linux: So erstellen Sie einen Zombie-Prozess

Ziel: Analysieren Sie, wie Zombie-Prozesse oder nicht mehr funktionierende Prozesse erstellt und aus der Prozesstabelle entfernt werden.

Ein Zombie-Prozess oder nicht mehr existierender Prozess ist ein Prozess, der die Ausführung abgeschlossen hat, aber noch einen Eintrag in der Prozesstabelle hat. Dies tritt bei untergeordneten Prozessen auf, die von einem übergeordneten Prozess mithilfe des Systemaufrufs fork() gegabelt, aber nicht vom übergeordneten Prozess mithilfe des Systemaufrufs wait() geerntet wurden.

Der übergeordnete Prozess muss einen wait() (oder waitpid()) Systemaufruf ausführen, um den Exit-Status des untergeordneten Prozesses abzurufen, sobald der untergeordnete Prozess beendet wurde. Wenn der wait() -Aufruf nicht vom übergeordneten Prozess ausgeführt wird, wird der untergeordnete Prozess zu einem Zombie-Prozess.

Ein SIGCHLD -Signal wird an den übergeordneten Prozess gesendet, wenn ein untergeordneter Prozess beendet wird. Für den übergeordneten Prozess muss eine SIGCHLD -Signalhandlerfunktion mit einem Aufruf von wait() definiert sein – dadurch wird der untergeordnete Prozess aus der Prozesstabelle entfernt.

Um Zombie-Prozesse aus einem System zu entfernen, kann das Signal SIGCHLD manuell mit dem Befehl kill an das übergeordnete System gesendet werden. Wenn sich der übergeordnete Prozess immer noch weigert, den Zombie-Prozess zu ernten, und wenn der übergeordnete Prozess beendet werden kann, besteht der nächste Schritt darin, den übergeordneten Prozess zu beenden. Wenn ein untergeordneter Prozess seinen übergeordneten Prozess verliert, wird init (PID 1) zu seinem neuen übergeordneten Prozess. init führt periodisch den Systemaufruf wait() aus, um alle Zombie-Prozesse mit init als übergeordnetem Prozess zu ernten.

Ich habe ein einfaches C-Programm geschrieben, um einen Zombie-Prozess zu erstellen.

Zombie.c – Erstellen eines Zombie-Prozesses

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

# include <stdio.h>
# include <stdlib.h>
# include <sys/Typen.h>
# include <sys/warten.h>
# include <unistd.h>
# include <errno.h>
int Hauptseite ()
{
pid_t child_pid;
int child_status;
child_pid = Gabel ();
wenn (child_pid > 0) {
// der übergeordnete Prozess schläft 30 Sekunden lang und wird ohne Aufruf von wait()
fprintf(stderr, „übergeordneter Prozess – % d\n“, getpid());
schlaf(30);
ausfahrt(0);
}
else wenn (child_pid == 0) {
// der untergeordnete Prozess wird sofort beendet
fprintf(stderr,“untergeordneter Prozess – %d\n“, getpid());
ausfahrt(0);
}
else wenn (child_pid == -1) {
// fork () Fehler
perror („fork () Aufruf fehlgeschlagen“);
beenden (-1);
}
else {
// dies sollte nicht passieren
fprintf(stderr, „unbekannter Rückgabewert von %d vom fork() -Aufruf“, child_pid);
exit (-2);
}
rückkehr 0;
}

Speichern Sie den obigen Code als zombie.c und kompilieren Sie ihn mit gcc .

$ gcc zombie.c -o zombie

Führen Sie als nächstes das Programm aus.

$ ./zombie parent process - 26570child process - 26571

Führen Sie von einem anderen Terminal aus a ps aus, um laufende Prozesse anzuzeigen. Sie werden einen Zombie-Prozess sehen.

$ 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>

Sobald der übergeordnete Prozess beendet ist (nach 30 Sekunden), wird der Zombie-Prozess vom init -Prozess aus der Prozesstabelle entfernt.

Mohamed Ibrahim

ibrahim = { interested_in(unix, Linux, android, open_source, reverse_engineering); Codierung (c, shell, PHP, python, java, javascript, nodejs, reagieren); plays_on (xbox, ps4); linux_desktop_user(wahr); }

Write a Comment

Deine E-Mail-Adresse wird nicht veröffentlicht.