2016-08-05 60 views
-1

Wenn ich den folgenden Code ausführenwarum vfork() geben Segmentierungsfehler

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
int main() 
{ 
    pid_t pid; 
    pid = vfork(); 
    printf("hello world\n"); 
} 
Output: 
hello world 
hello world 
hello world 
Segmentation fault 

Ich weiß, dass es sei denn, exec() oder _exit() aufgerufen wird dann vfork() kann in seltsame Art und Weise verhalten, wenn wir versuchen, ändere irgendeine Variable, aber kann jemand bitte erklären, was genau passiert? Warum Hallo Welt wird 3 mal gedruckt? Liegt es daran, dass printf() gepuffert wird? und schließlich, warum ein Seg-Fehler gerade dann auftritt, wenn Eltern versuchen, zurückzukehren?

+2

Wenn Sie wissen, dass es ein undefiniertes Verhalten auslöst, warum fragen Sie nach dem spezifischen Verhalten? –

+2

das ist die Bedeutung von undefiniertem Verhalten, kann es nicht anders erklärt werden, würde es definiert werden –

+0

"Verhalten auf seltsame Weise" ist keine gute Charakterisierung von "hat undefined Verhalten". Insbesondere liegt das Versagen bei einem Segfault innerhalb der weitgehend willkürlichen Grenzen eines undefinierten Verhaltens. Also drucke "Hallo Welt" dreimal, unabhängig davon, ob es irgendeinen Code in deinem Programm gibt, der irgendetwas über diese Ausgabe erklären könnte. Sie können nicht berechtigterweise über undefiniertes Verhalten argumentieren. –

Antwort

1

(From POSIX.1) Die vfork() Funktion hat, die gleiche Wirkung wie Gabel (2), Ausnahme, daß das Verhalten, wenn der Prozess erstellt von vfork() undefiniert ist entweder modifiziert keine anderen Daten als eine Variable des Typs pid_t wird verwendet, um den Rückgabewert von vfork() zu speichern, oder gibt die Funktion zurück, in der vfork() aufgerufen wurde, oder ruft eine andere Funktion auf, bevor _exit (2) oder eine der Funktionen der exec (3) -Familie erfolgreich aufgerufen wird .

Scheint, wie Sie sich für vfork alle die Bedingungen verstoßen. Also dann klappt es nicht.

0

Das Stück Code, den ich geschrieben habe, ist eine Katastrophe und wird in einer nicht definierten Weise verhalten, aber die plausible Erklärung für ein solches Verhalten sein könnte: -

Da der Adressraum gemeinsam genutzt wird und wenn das Kind nicht zurückkehrt von _exit() oder exec(), daher würde Spülung von I/O-Puffern durchgeführt werden (was zu einer zusätzlichen Hallo-Welt-Anweisung führt) und während des Bereinigungsprozesses, wenn Speicher zu printf() freigegeben wird, kann es Funktionsaufrufe auf dem Stapelrahmen stellen Elternteil ist immer noch fest. Nach der Rückgabe hat das übergeordnete Element möglicherweise keine Rücksprungadresse auf dem Stapel, um zu einem beliebigen Benutzer zurückzukehren, was zu einem Segmentierungsfehler führt.