2012-05-14 8 views
8

पर stdout वापस नहीं करता है मैं पाइथन से निष्पादन योग्य सी चला रहा हूं और यह निष्पादन योग्य कभी-कभी segfaults। जब यह subprocess मॉड्यूल segfaults stdout या stderr में कुछ भी वापस नहीं करता है।पायथन उपप्रोसेसर मॉड्यूल segfault

नमूना कोड:

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 

a.out के लिए स्रोत है:

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

./a.out के उत्पादन में है:

hello world 
Floating point exception 

अजगर कोड के उत्पादन में (है लिनक्स में , पायथन 2.7):

out: "" 
err: "" 
-8 

क्या यह क्रैश होने पर निष्पादन योग्य के आउटपुट को प्राप्त करने का कोई तरीका है?

एक स्ट्रिंग संदेश में रिटर्नकोड का अनुवाद करने के लिए एक सामान्य विधि भी अच्छा होगा।

उत्तर

2

एप्लिकेशन निश्चित रूप से सेगमेंटेशन गलती से मुकाबला करने से पहले अपने आउटपुट बफर को फ्लश नहीं कर रहा है।

डिफ़ॉल्ट रूप से, सी stdio लाइब्रेरी stdout के लिए बफरिंग कॉन्फ़िगर करती है ताकि बफर को लाइन के हर छोर पर फ़्लश किया जा सके, लेकिन केवल stdout एक tty है। यही कारण है कि आप करें आउटपुट देखें जब आप कमांड लाइन से a.out चलाते हैं।

आप सीधे सी प्रोग्राम को पायथन पक्ष से नहीं बदल सकते हैं। लेकिन आप कर सकते हैं यह stdout, अर्थात् एक छद्म tty के लिए उपयोग करने के लिए एक tty है। एक छद्म टर्मिनल खोलने और स्थापित करने का विवरण नियमित पाइप स्थापित करने से कहीं अधिक जटिल है, लेकिन कुछ मॉड्यूल हैं जो आपकी मदद करेंगे: Pexpect और this SO question देखें।

3

आपका सी प्रोग्राम अपने आउटपुट बफर को फ्लश नहीं कर रहा है।

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

अब अपने कार्यक्रम (जो मैं लिखने में कोई त्रुटि ठीक करने के लिए संपादित) सही उत्पादन का उत्पादन:

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

वापसी इस समस्या को हल करने के लिए सबसे आसान तरीका है unbuffered उत्पादन STDOUT के मोड बदलने के लिए है मेरे मैक पर कोड 0 है, भ्रमित रूप से, क्योंकि सिग्नल के लिए समाप्त किए गए प्रोग्राम में रिटर्न कोड नहीं है।

+0

अच्छा समाधान, यदि आप सी कोड को नियंत्रित करते हैं और इसमें 'setvbuf' कॉल जोड़ने और recompile जोड़ने में सक्षम हैं। मैं तीसरे पक्ष के सी कोड को मान रहा था जो इसे संशोधित करने के सवाल से बाहर है। – Celada

+0

ठीक है, अगर आपका तीसरा पक्ष कोड क्रैश होने से पहले अपने स्टडआउट को फ्लश नहीं करता है, तो आप ऐसा नहीं कर सकते हैं। – vy32