2010-11-22 6 views
51

Wenn ich laufen die klassische bash forkbomb:Warum funktionieren C-Forkbombs nicht wie Bashs?

:(){ :&:&};: 

mein System hängt nach wenigen Sekunden.

Ich versuchte, ein forkbomb in C zu schreiben, hier ist der Code:

#include <unistd.h> 

int main() 
{ 
    while(1) { 
     fork(); 
    } 
    return 0; 
} 

Als ich es das System laufen wird weniger reagieren, aber ich kann diesen Prozess töten (auch nach Minuten) drückt ^C einfach.


Der obige Code unterscheidet sich von der ursprünglichen bash forkbomb ich geschrieben: es ist etwas mehr wie:

:() 
{ 
    while true 
    do 
     : 
    done 
} 

(ich habe es nicht testen, weiß nicht, ob es würde hängen das System).

Also habe ich auch versucht, die ursprüngliche Version zu implementieren; Hier ist der Code:

#include <unistd.h> 

inline void colon(const char *path) 
{ 
    pid_t pid = fork(); 
    if(pid == 0) { 
     execl(path, path, 0); 
    } 
} 

int main(int argc, char **argv) 
{ 
    colon(argv[0]); 
    colon(argv[0]); 
    return 0; 
} 

aber noch nichts: ich es laufen kann und dann ist es leicht zu töten. Es ist nicht hängen mein System.


Warum?

Was ist das Besondere an bash forbombombs? Weil bash viel mehr Speicher/CPU benötigt? Weil bash-Prozesse viel mehr Systemaufrufe aufrufen (zB um auf das Dateisystem zuzugreifen) als meins?

+0

Wie das Sprichwort sagt, wissenschaftliche Durchbrüche werden selten von "Eureka!" Begleitet, häufig begleitet von "Hmm, das ist seltsam." –

Antwort

44

Dieses C-Programm ist winzige, ernsthaft winzig. Außerdem ist es sehr effizient, ein solches Programm zu forkeln. Ein Interpreter wie Bash ist jedoch in Bezug auf die RAM-Nutzung viel teurer und muss ständig auf die Festplatte zugreifen.

Versuchen Sie es viel länger. :)

+26

Moderne Unixe neigen dazu, Copy-on-Write für virtuellen Speicher zu verwenden. Wenn nicht jeder Prozess tatsächlich in einen Speicherort schreibt, werden alle die gleichen physischen Seiten verwenden, selbst nach dem 'exec'. Setzen Sie ein paar zufällige mallocs in und schreiben Sie in die Malloced Erinnerung. Ich denke, das wird die Maschine töten. – JeremyP

+0

Ja, ich habe schon diese Dinge zitiert, aber welche von denen sind diejenigen, die das System hängen und warum? Wenn ich für irgendeinen Prozess spawne, ordne ich 1MB Speicher auf dem Heap/Stack zu, hängt es mein System? Oder wenn ein Prozess eine Sekunde intensiver Berechnung ausführt? Oder wenn irgendein Prozess einige Systemaufrufe aufruft? – peoro

+3

@peoro: Technisch gesehen hast du nicht. Mein Punkt war nicht, dass jeder neue Prozess wenig Speicher benötigt, sondern dass er tatsächlich keinen zusätzlichen Speicher verwendet (abgesehen von Kernel-Strukturen). Wenn Sie eine Verzweigung ausführen, verwendet der untergeordnete Prozess genau die gleichen physischen Seiten wie die übergeordneten Elemente, bis etwas in den Speicher geschrieben wird. Sogar mit exec wird das ausführbare Bild geteilt. Eine neue Stapelseite wird erstellt, aber der große Performance-Killer wird ausgetauscht und das wird nicht passieren, wenn Sie nicht einige Schreibvorgänge ausführen. – JeremyP

3

In Ihrem Bash ForkBomb, fügen Sie neue Prozesse in neue Hintergrundprozessgruppen, so dass Sie ^C ihnen nicht werden können.

0

Das ist im Grunde wegen der Größe. Wenn Sie die Bash Gabel Bombe laufen läd es große Monster-Programme in den Speicher (in Bezug auf Ihre c-Programm) jeder von ihnen beginnen, auf Ihre CPU-Ressourcen hoggen. Definitiv, wenn große Monster anfangen zu reproduzieren Probleme schneller kommt als wenn Bienen beginnen zu tun gleich. So hängt der Computer sofort.Wenn Sie jedoch Ihre c ausführbare Datei läuft für lange hält es das System zu hängen.Just, dass die Zeit wird viel viel mehr. Wenn Sie die Größe von bash mit der Größe von c-Programm vergleichen möchten, überprüfen Sie/proc // status. zuerst mit pid jeder ausgeführten Instanz von bash und dann mit pid jeder laufenden Instanz eines C-Programm

3

Die echte Ursache dafür ist, dass der Prozess, den Sie in BASH erstellen wird von den übergeordneten abgelöst. Wenn der übergeordnete Prozess (derjenige, den Sie ursprünglich gestartet haben) beendet wird, läuft der Rest der Prozesse weiter.Aber in den C-Implementierungen haben Sie aufgelistet, dass die untergeordneten Prozesse sterben, wenn das übergeordnete Element getötet wird. Es genügt also, den anfänglichen Prozess zu reduzieren, den Sie gestartet haben, um den gesamten Prozess der Everforking-Prozesse herunterzufahren.

Ich bin noch nicht mit einer C-Forkbomb-Implementierung gekommen, die untergeordnete Prozesse trennt, so dass sie nicht getötet werden, wenn der Elternteil stirbt. Links zu solchen Implementierungen würden geschätzt werden.