2012-05-14 4 views
8

Ich führe eine C ausführbare Datei von Python und diese ausführbare Datei manchmal segfaults. Wenn es segfaults gibt das Subprozessmodul nichts in stdout oder stderr zurück.Python Subprozess-Modul gibt nicht Stdout auf segfault zurück

Beispielcode:

import subprocess 

proc = subprocess.Popen(['./a.out'], stdin=subprocess.PIPE, 
     stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
out, err = proc.communicate() 
print 'out: "%s"' % out 
print 'err: "%s"' % err 
print proc.returncode 

Die Quelle für a.out ist:

int main() { 
    printf("hello world\n"); 
    int x = 1/0; 
} 

Der Ausgang des ./a.out ist:

hello world 
Floating point exception 

Der Ausgang des Python-Code ist (in Linux , Python 2.7):

01.235.

Gibt es eine Möglichkeit, die Ausgabe der ausführbaren Datei zu erhalten, selbst wenn es abstürzt?

Eine generische Methode, um Rückkehrcode in eine Zeichenfolge Nachricht zu übersetzen, wäre auch nett.

Antwort

2

Die Anwendung spült ihre Ausgabepuffer fast sicher nicht, bevor sie auf den Segmentierungsfehler trifft.

Standardmäßig konfiguriert die C stdio-Bibliothek die Pufferung für stdout, so dass die Puffer an jedem Ende der Leitung gespült werden, aber nur stdout ist ein Tty. Deshalb sollten Sie tun die Ausgabe zu sehen, wenn Sie a.out von der Kommandozeile ausgeführt werden.

Sie können das C-Programm nicht direkt von der Python-Seite aus ändern. Aber was Sie kann tun geben, ist es ein tty für seine stdout zu verwenden, nämlich eine Pseudo-tty. Die Einzelheiten der Öffnung und einen Pseudo-Terminal der Einrichtung sind viel komplizierter als eine regelmäßige Rohr einrichten, aber es gibt einige Module, die Ihnen helfen: Siehe Pexpect und this SO question, unter anderem.

3

Ihr C-Programm wird Spülung nicht seine Ausgangspuffer. Der einfachste Weg, um dieses Problem ist es, den Ausgabemodus von STDOUT ungepufferte zu ändern:

#include <stdio.h> 
int main(int argc,char **argv) { 
    setvbuf(stdout,_IONBF,0,0); 
    printf("hello world\n"); 
    int x = 1/0; 
} 

Jetzt Ihrem Programm (die ich bearbeiten einen Tippfehler zu beheben) erzeugt die korrekte Ausgabe:

$ python2.7 x.py 
out: "hello world 
" 
err: "" 
0 
$ 

Die Rückkehr Code ist auf meinem Mac 0, verwirrend, da Programme, die für ein Signal beendet werden, keinen Rückgabecode haben.

+0

Gute Lösung, wenn Sie den C-Code steuern und in der Lage sind, den 'setvbuf'-Aufruf hinzuzufügen und neu zu kompilieren. Ich nahm C-Code von Drittanbietern an, der nicht geändert werden kann. – Celada

+0

Nun, wenn Ihr Code von Drittanbietern nicht seine stdout nicht spülen, bevor es abstürzt, gibt es nicht viel Sie tun können. – vy32