I'm a long time SO reader, but this is my first question here.
I'm writing a Python 3 program (which I'm currently self-learning) to compile and run a group of C++ programs that supposed to be doing the same thing (students' submissions for an assignment) and compare their output to the expected output I already have in a text file.
I'm looking for a way to run these executables that allows me to:
- Terminate an executable after a certain time limit (say, 10 seconds) if it doesn't end.
- Capture all the output from the executable (including stdout, stderr, and any "shell" messages like segmentation faults, memory/core dump,..etc)
- Even if the executable crashes, or has been forcefully terminated (after exceeding the allowed time), I need to capture the "partial" output up to that point.
- Nothing goes to the screen (No output or error messages).
Everything I have tried so far (from answers to similar questions) is missing something. I couldn't find one that covers all my needs (the points above). Here are some examples:
check_output() (like in this question) does not collect the output if the executable crashes, and some messages (like core dump) still go to the screen.
Popen() (as in this) does not seem to terminate the executable (when time exceeded). The python thread ends (I hope I'm using the correct terms here), but the executable keeps running.
Even though methods like os.system() are not encouraged, but I tried them anyway, and they didn't perform any better.
I appreciate it a lot if any one can point me to a way to achieve this. I apologize for any grammatical mistakes as English is not my first language. Please let me know if any further details are needed. Thank you,
EDIT:
Here is a minimum replica of my python code:
from subprocess import STDOUT, check_output, TimeoutExpired
timeLimit = 3 # seconds
strOutput = ''
try:
output = check_output('./a.out', stderr = STDOUT, timeout = timeLimit)
strOutput = ''.join(map(chr, output))
except TimeoutExpired as e:
strOutput += 'Error: Time limit exceeded, terminated..'
except Exception as e:
strOutput += 'Error: ' + str(e)
f = open('report.txt','w')
f.write(strOutput)
f.close()
I'm also including some C++ samples that contain some bugs to create the executables to be used to test the previous code. They all can be compiled as: g++ programName.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "This one is working correctly!" << endl;
}
The following code causes a "division by zero" error. The statement printed before this error is not captured by check_output()
#include <iostream>
using namespace std;
int main()
{
cout << "Trying to divide by zero.." << endl;
cout << 3 / 0 << endl;
}
This code waits for an unexpected input (should be terminated by the script after the specified timeout)
#include <iostream>
using namespace std;
int main()
{
int x;
cout << "Waiting for an unexpected input.." << endl;
cin >> x;
}
I couldn't find a reliable way to reproduce the core dump issue. Core dump is a special case issue because check_output() cannot capture its output (it goes directly/only to the screen).
P.S. I couldn't add the tag 'check_output()', I do not have enough reputation.