9

我正在从 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

即使它崩溃了,有没有办法获得可执行文件的输出?

将返回码转换为字符串消息的通用方法也很好。

4

2 回答 2

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,因为因信号而终止的程序没有返回码。

于 2012-05-14T03:14:10.363 回答
3

应用程序几乎可以肯定在遇到分段错误之前不会刷新其输出缓冲区。

默认情况下,C stdio 库配置缓冲,stdout以便在行的每一端刷新缓冲区,但只有stdouttty。这就是从命令行运行时确实看到输出的原因a.out

你不能直接让 C 程序从 Python 端改变它。但是你可以做的是给它一个 tty 来使用它stdout,即一个伪 tty。打开和设置伪终端的细节比设置常规管道复杂得多,但有一些模块可以帮助您:请参阅Pexpect这个 SO question等。

于 2012-05-14T03:06:52.207 回答