2016-08-05 66 views
-1

Was ich erreichen möchte, ist das folgende: Spawn einen neuen Childprocess (pchild), der nicht seinen eigenen verwendet, aber der Speicherblock von seinem Elternprozess (pparent) .Forking eines Child-Prozesses, der seine eigene Speicherkopie nicht verwendet

Warum möchte ich dieses Verhalten erreichen: Denken Sie an mehrere Tests, bei denen der erste zu segvault führt. Normalerweise würde Ihr Prozess hier wegen segfault stoppen, alle anderen Tests würden nicht mehr ausgeführt werden. Daher möchte ich jeden Test in seinem eigenen Prozess kapseln.

Hauptproblem: Sobald ich laichen einen Prozess es seine eigene Speicherkopie bekommt (na ja, ich bin der Tatsache bewusst, dass dies für alle OS nicht ganz wahr ist, wegen ‚copy-on-write‘ -Technik). Denken Sie z.B. Testen der Baumfunktionalität, wobei ich eine Knotenstruktur mit zwei Zeigern zu anderen Knoten habe. Sobald ich einen Knoten z. Mit Hilfe einer Pipe oder eines geteilten Speicherblocks zeigen diese Zeiger auf eine Adresse, die Teil des Speicherblocks des pchilds ist, und daher erhalte ich einen segvault, wenn ich von parent versuche, den childnode durch Verfolgen der Zeiger innerhalb der Knotenstruktur zu erhalten.

Ein Thread ist nicht brauchbar, aufgrund des Hauptverhaltens eines Betriebssystems, das einmal einen segfault passiert. (Töten von Kind und Vater wegen "unklarem Zustand").

Was ich bisher (nur Gabel Testteil):

int main (void) { 
    // forking 
    pid_t pid = fork(); 
    if (pid < 0) { 
     // somewhat went wrong 
     printf("An error occured!"); 
    } else if (pid != 0) {        // inside parent 
     // closing writing end, as not needed 
     if(wait(NULL)!=0){ 
      printf("Segfault in Child\n"); 
     } else { 
      printf("Everyone is done!\n"); 
     } 
    } else { 
     printf("Child forked"); 
     char *s = (char *)0xDEADBEEF; 
     *s = 'a'; 
     printf("this probally is never executed due to segfault\n"); 
    } 
    return 0; 
} 

Jetzt ist meine Idee zu versuchen, nur den pchild Zugriff auf das Speichersegment von pParent zu lassen. Ich würde jede Idee begrüßen, wie man das macht. Grüße, Lars

+1

Sind Sie sicher, dass Sie das brauchen? Wenn ein Test abstürzt, was bringt es, weitere Tests durchzuführen? – fuz

+1

Wenn Sie unter Linux sind, können Sie dieses wahnsinnige Schema möglicherweise über 'clone()' machen. – EOF

+0

fork_and_exec gdb und an den Hauptprozess anhängen. – joop

Antwort

2

Ihre Frage ist nicht sehr klar, aber ich denke, Sie haben eine XY problem.

Mein Verständnis ist, dass Sie eine Reihe von Tests ausführen möchten, wo jeder Test die Ergebnisse früherer Tests, die erfolgreich waren, aber keine Tests, die abgestürzt/fehlgeschlagen sind, sehen. Wenn dies der Fall ist, wäre ein Ansatz,:

  1. fork vor jedem Test
  2. den Tests in dem Kind Ausführen.
  3. Wenn der Test erfolgreich war, haben Sie den Elternausgang oder warten Sie einfach, während das Kind wieder forkelt und den nächsten Test in seinem Kind ausführt. Wenn der Test fehlgeschlagen ist, lassen Sie die Elterngabel erneut laufen, um den nächsten Test durchzuführen.

könnte Ein weiterer Ansatz Ihre Datenstrukturen nur im gemeinsam genutzten Speicher durch mmap mit MAP_SHARED|MAP_ANON, zugeordnet zu halten, aber dann alle Ergebnisse Junk wäre Zukunft Test, wenn ein Test sie in einem inkonsistenten Zustand.

Ihre Idee, alle Speicher zwischen den Prozessen zu teilen, ist technisch möglich, aber sie wird sofort explodieren, weil sie den Zustand des anderen überdecken.

+0

Nun, diese Antwort ist nicht so hilfreich. vor allem Schritt 1 und 2 sind die Sache, die ich machen möchte. was das Problem damit ist, ist ein schöner Rückgabewert. Da Eltern und Kind getrennte Speicher haben, wird durch das Zurückgeben einer Struktur, die Zeiger enthält (und in untergeordnetes Element zugewiesen wurde) von Kind zu Elternelement, alles durcheinandergebracht. Weil diese Zeiger zu child mem führen, sobald ich ihnen folge, wenn ich im Elternteil bin, erhalte ich einen segfault ... –

+0

Die meisten des Tests bauen aufeinander nicht auf! - Vergessen, das zu sagen, tut mir leid! –

+1

@LarsPrehn: Wenn Sie nur Ergebnisse vom Kind zum Elternteil zurückgeben wollen, senden Sie sie über eine Pipe oder verwenden Sie eine gemeinsame mmap. Deshalb habe ich gesagt, dass Sie ein XY-Problem haben - Sie fragen, wie man einen schrecklichen komplexen Hack macht, um etwas zu erreichen, das mit Standardwerkzeugen, die wohldefiniertes Verhalten haben, einfach ist. –

0

Jeder Prozess hat seinen eigenen virtual memory Adressraum, so dass es keine Möglichkeit gibt, eine RAM Adresse zu einem anderen Prozess zu geben (gut können Sie eine Nummer senden, aber in einem anderen virtual memory Adressraum wird es auf andere 'echte' Stelle zeigen).

Alles, was Sie brauchen, ist ein weiterer Thread. Threads desselben Prozesses teilen sich einen virtual memory Speicherplatz.

+0

"Jeder Prozess hat seinen eigenen virtuellen Speicher Adressraum, so dass es keine Möglichkeit gibt, eine RAM-Adresse zu einem anderen Prozess zu geben" - definitiv nicht wahr! Siehe mmap ... "Alles was Sie brauchen ist ein anderer Thread. Threads desselben Prozesses teilen sich einen virtuellen Speicherplatz." ... Wie ich in meiner Frage gesagt habe, sind Threads überhaupt nicht hilfreich. Wenn ich das nicht schon gewusst hätte, wie könnte ich diese Frage aufstellen? –

-2

versuchen, vfork() zu verwenden; anstelle von fork(); systemcall. teilt die Ressourcen von Eltern- und Kindprozess.

+0

Da die einzige zulässige Aktion, die das Kind nach 'vfork()' ausführen kann, '_exit()' oder 'exec()' ist, ist es nicht sofort offensichtlich, wie es dem OP helfen würde. – EOF