为什么由于分段错误导致子进程不能立即死亡?
问题描述:
我需要编写一个接受某个输入并打印相应输出的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
,表示该进程仍然存在。
现在,如果下面的变化到由除块:
a.wait()
print a.returncode
if a.returncode == -11:
print "Segmentation Fault Occurred"
问题已解决。输出显示Popen对象的返回码是-11,并且“屏幕出现分段错误”被打印到屏幕上。
如果我尝试模拟由于被零除的浮点异常,情况完全相同。
这是为什么发生?
答
从文档
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++程序。
编程是残酷的。 (你知道,孩子们被杀死了。) – keeganjk