2

我需要编写一个接受某个输入并打印相应输出的 C++ 代码。此代码旨在使用 Python 子流程模块运行。无论输入和输出如何,我都需要确保 Python 代码不会由于 C++ 代码遇到的运行时错误而过早终止。C++代码的基本性质如下

int main()
{
  /*The pointer is initialized to NULL to simulate a segmentation fault
    Also the n is meant for simulating input.*/
  int *p=NULL,n;   
  cin>>n;
  cout<<*p<<endl;  //This causes a segmentation fault.
}

运行它的 Python 代码如下:

from subprocess import *
from signal import *

def handler(signum,frame):
    raise RuntimeError("Runtime Error")

call(["g++","try.cpp"])
a = Popen(["stdbuf","-i0","-o0","-e0","./a.out"],stdin = PIPE,stdout = PIPE)
try:
    #Handler for signal due to termination of child process
    signal(SIGCHLD,handler)    
    a.stdin.write("1\n")
    temp = a.stdout.readline()
except RuntimeError as e:
    print e
    print a.returncode   

#Returncode of process killed due to SIGSEGV is -11
    if a.returncode == -11:   
        print "Segmentation Fault Occurred"

这就是问题所在。尽管 C++ 代码遇到分段错误,但会调用信号处理程序并RuntimeError引发 ,但 Popen 对象的返回码是none,表明进程仍然存在。
现在,如果对 except 块进行以下更改:

a.wait()
print a.returncode        
if a.returncode == -11:   
    print "Segmentation Fault Occurred"

问题已解决。输出显示 Popen 对象的返回码为 -11 并且“发生分段错误”打印到屏幕上。
如果我尝试模拟由于被零除而导致的浮点异常,也会发生完全相同的情况。
为什么会这样?

4

1 回答 1

1

从文档

Popen.wait() 等待子进程终止。设置并返回 returncode 属性。

所以returncode直到wait被调用才设置。

或者,您可以执行非阻塞检查以查看进程是否使用 终止,如果终止poll,它也会设置returncode

Popen.poll() 检查子进程是否已经终止。设置并返回 returncode 属性。

请注意,您实际上并不需要signal调用(不确定它在 Windows 上是否可移植)。代码可以这样简化:

a = Popen(["stdbuf","-i0","-o0","-e0","./a.out"],stdin = PIPE,stdout = PIPE)
a.stdin.write("1\n")
a.stdin.flush()
temp = a.stdout.readline()
if temp:
    # do something
    print("output "+temp)
else:
    # empty string: recieved process has ended, probably unexpectedly
    # because it should have printed something
    pass

returncode = a.wait()

#Returncode of process killed due to SIGSEGV is -11
if returncode  == -11:   
    print("Segmentation Fault Occurred")

请注意,您必须a.stdin.flush()确保输入到达 c++ 程序。

于 2016-12-25T12:44:30.233 回答