我正在从Python运行C可执行文件,这个可执行文件有时会出现段错误。当它发生段错误时,子进程模块不会在stdout或stderr中返回任何内容。
示例代码:
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
Python代码的输出是(在Linux中,python 2.7):
out: ""
err: ""
-8
有没有办法获得可执行文件的输出,即使它崩溃了?
将returncode转换为字符串消息的通用方法也很不错。
答案 0 :(得分:3)
应用程序几乎肯定不会在遇到分段错误之前刷新其输出缓冲区。
默认情况下,C stdio库为stdout
配置缓冲,以便在每一行都刷新缓冲区,但只有stdout
是tty。这就是当你从命令行运行a.out
时做看到输出的原因。
你不能直接让C程序从Python端改变它。但是你可以做的是为它的stdout
提供一个tty,即伪tty。打开和设置伪终端的细节比设置常规管道要复杂得多,但有一些模块可以帮助您:请参阅Pexpect和this SO question等。
答案 1 :(得分:3)
您的C程序没有刷新其输出缓冲区。解决此问题的最简单方法是将STDOUT的输出模式更改为无缓冲:
#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
$
我的Mac上的返回码是0,令人困惑,因为为信号终止的程序没有返回码。