Python的子模块不会对段错误返回标准输出(Python subprocess module do

2019-06-24 09:42发布

我正在从Python的一个C可执行文件和该可执行文件有时会出现segfaults。 当它出现segfaults的子模块没有返回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中,蟒2.7):

out: ""
err: ""
-8

有没有办法让即使它崩溃的可执行文件的输出?

一个通用的方法来翻译返回码为一个字符串消息,也将是不错。

Answer 1:

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

默认情况下,将C stdio库配置为缓冲stdout ,这样的缓冲器在行上每一个满脸通红,但只能是stdout是一个tty。 这就是为什么看到的输出当您运行a.out命令行。

你不能直接使C程序从Python方改变这一点。 但是,你能做的就是给它一个TTY使用其stdout ,也就是伪终端。 打开和建立伪终端的细节比建立一个常规的管道比较复杂,但也有一些模块,这将有助于您:请参见Pexpect的和这太问题 ,等等。



Answer 2:

你的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
$

返回码0在我的Mac,容易引起混淆,因为被终止的信号程序没有返回代码。



文章来源: Python subprocess module does not return stdout on segfault