2014-05-15 12 views
5

Ich versuche, eine Anwendung von einer anderen in C++ aufzurufen. Die eingebettete Anwendung unterliegt aufgrund von Syntaxfehlern in einer Eingabedatei Segmentationsfehlern, sodass das äußere Programm für das erneute Ausführen der internen und Protokollierungsfehler zuständig ist.Verwirrender Rückgabewert von eingebetteter Anwendung

Meine unmittelbare Idee war, sich auf den Rückgabewert des inneren Programms zu verlassen. Also begann ich damit zu experimentieren. Ich schrieb ein Dummy-Programm in Inner.cpp:

#include <iostream> 

int main() 
{ 
    std::cout << "Inner" << std::endl; 
    return 22; 
} 

Dann schrieb ich dies in Outer.cpp:

#include <cstdlib> 
#include <iostream> 

int main() 
{ 
    int retval = system("~/Inner"); 
    std::cout << "Returned: " << retval << std::endl; 
    return 0; 
} 

Haben diese verwirrende Ausgabe:

Inner 
Returned: 5632 

So liest ich begann. Ich fand bald heraus, dass nur die 8 LS-Bits durchlaufen werden, die unsigned behandelt werden. Aber würde das nicht nur bedeuten, keine Werte über 255 zu verwenden? Warum bekomme ich diesen seltsamen Wert?

Also fing ich an, die Bits zu betrachten.

What I expected: 22 -> 0000 0000 0000 0000 0000 0000 0001 0110 
What I got: 5632 -> 0000 0000 0000 0000 0001 0110 0000 0000 

Woah, das ist das gleiche Muster, nur verschoben. Und in der Tat, wenn ich meine Linie geändert:

std::cout << "Returned: " << (retval >> 8) << std::endl; 

Ich habe immer die genaue Zahl ich wollte. Ich kann jedoch nichts darüber finden, warum dies geschieht, und jetzt mache ich mir Sorgen, dass es noch viele Überraschungen gibt, wenn ich zu dem Teil komme, wo ich einen SIGSEGV im inneren Programm erkennen und die Ausführung fortsetzen muss im Äußeren.

Meine Frage ist letztlich: Was ist der beste Weg, um eine (Kommandozeilen-) Anwendung sicher in eine andere einzubetten, wenn man bedenkt, dass sie einige minimale Daten übertragen müssen, und die aufgerufene eine Segmentierung verursachen könnte? (Auch, was ist die bitshift Sache mit dem Rückgabewert?)

Ubuntu 12.04.4 LTS 
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 
+1

Warum nicht einfach die Fehler in der eingebetteten App beheben, damit sie nicht abstürzt? –

+0

@PaulR Es gibt keine Fehler. Es arbeitet mit riesigen Eingabedateien, die von einer externen Quelle kommen, es gibt keine Zeit zum Crawlen und es werden vor dem Parsen alle Syntaxfehler überprüft. – Innkeeper

+1

Wenn die App abstürzt, wenn ein Syntaxfehler in der Eingabedatei nicht behandelt wird, würde ich das als einen ziemlich ernsten Fehler bezeichnen. –

Antwort

2

Sie wollen fork, exec und wait verwenden, so etwas wie:

int status; 
if ((pid = fork()) == 0) // child proc 
    exec("~/Inner"); 
else // parent 
    waitpid(-1, &status, 0) 
1

Verwenden WEXITSTATUS

int retval = system("~/Inner"); 
retval = WEXITSTATUS(retval); 

wird tun