I need to write a C++ code which accepts a certain input and prints the respective output. This code is meant to be run using the Python subprocess module. Regardless of inputs and outputs, I need to make sure that the Python code does not terminate prematurely due to runtime errors the C++ code encounters. The basic nature of the C++ code is as follows
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.
}
The Python code which runs it, is as follows:
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"
This is the issue. Even though the C++ code experiences a segmentation fault, the signal handler is invoked, the RuntimeError is raised, but the returncode of the Popen object is none, indicating that the process still lives.
Now if the following change is made to the except block:
a.wait()
print a.returncode
if a.returncode == -11:
print "Segmentation Fault Occurred"
The issue is resolved. The output shows that the returncode of the Popen object is -11 and "Segmentation Fault Occurred" is printed to the screen.
The exact same happens if I try to simulate a floating point exception due to divide-by-zero.
Why does this happen?
From the documentation
So
returncodeis not set untilwaitis called.Alternately you could perform a non-blocking check to see if process is terminated using
poll, which would setreturncodeas well if terminated.note that you don't really need the
signalcall (not sure if it's portable on Windows). The code could be simplified like this:note that you have to
a.stdin.flush()to be sure the input reaches the c++ program.