From a9d7b48b6a5a79bf619500463d89f03e8ca1b7bb Mon Sep 17 00:00:00 2001 From: mahesh Date: Tue, 4 Apr 2017 13:00:41 +0530 Subject: Kills stray processes in code, hook and stdio evaluator --- yaksh/base_evaluator.py | 5 +++-- yaksh/bash_stdio_evaluator.py | 3 ++- yaksh/cpp_stdio_evaluator.py | 3 ++- yaksh/hook_evaluator.py | 7 +++++-- yaksh/java_stdio_evaluator.py | 3 ++- yaksh/stdio_evaluator.py | 13 ++++++++++--- 6 files changed, 24 insertions(+), 10 deletions(-) (limited to 'yaksh') diff --git a/yaksh/base_evaluator.py b/yaksh/base_evaluator.py index 071008f..653aef0 100644 --- a/yaksh/base_evaluator.py +++ b/yaksh/base_evaluator.py @@ -7,6 +7,7 @@ from os.path import join, isfile from os.path import isdir, dirname, abspath, join, isfile, exists import subprocess import stat +import signal # Local imports @@ -30,11 +31,11 @@ class BaseEvaluator(object): stdout and stderr. """ try: - proc = subprocess.Popen(cmd_args, *args, **kw) + proc = subprocess.Popen(cmd_args,preexec_fn=os.setpgrp, *args, **kw) stdout, stderr = proc.communicate() except TimeoutException: # Runaway code, so kill it. - proc.kill() + os.killpg(os.getpgid(proc.pid), signal.SIGTERM) # Re-raise exception. raise return proc, stdout.decode('utf-8'), stderr.decode('utf-8') diff --git a/yaksh/bash_stdio_evaluator.py b/yaksh/bash_stdio_evaluator.py index 334620d..1ce729a 100644 --- a/yaksh/bash_stdio_evaluator.py +++ b/yaksh/bash_stdio_evaluator.py @@ -49,7 +49,8 @@ class BashStdIOEvaluator(StdIOEvaluator): shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE + stderr=subprocess.PIPE, + preexec_fn=os.setpgrp ) success, err = self.evaluate_stdio(self.user_answer, proc, self.expected_input, diff --git a/yaksh/cpp_stdio_evaluator.py b/yaksh/cpp_stdio_evaluator.py index b302fa4..d211bb7 100644 --- a/yaksh/cpp_stdio_evaluator.py +++ b/yaksh/cpp_stdio_evaluator.py @@ -82,7 +82,8 @@ class CppStdIOEvaluator(StdIOEvaluator): shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE + stderr=subprocess.PIPE, + preexec_fn=os.setpgrp ) success, err = self.evaluate_stdio(self.user_answer, proc, self.expected_input, diff --git a/yaksh/hook_evaluator.py b/yaksh/hook_evaluator.py index 0819ec9..b86640c 100644 --- a/yaksh/hook_evaluator.py +++ b/yaksh/hook_evaluator.py @@ -7,7 +7,8 @@ import os from .file_utils import copy_files, delete_files from .base_evaluator import BaseEvaluator from .grader import TimeoutException - +import signal +import psutil class HookEvaluator(BaseEvaluator): def __init__(self, metadata, test_case_data): @@ -65,10 +66,12 @@ class HookEvaluator(BaseEvaluator): check = hook_scope["check_answer"] success, err, mark_fraction = check(self.user_answer) except TimeoutException: + processes = psutil.Process(os.getpid()).children(recursive=True) + for process in processes: + process.kill() raise except Exception: msg = traceback.format_exc(limit=0) err = "Error in Hook code: {0}".format(msg) del tb return success, err, mark_fraction - \ No newline at end of file diff --git a/yaksh/java_stdio_evaluator.py b/yaksh/java_stdio_evaluator.py index 48f265d..4e9238f 100644 --- a/yaksh/java_stdio_evaluator.py +++ b/yaksh/java_stdio_evaluator.py @@ -67,7 +67,8 @@ class JavaStdIOEvaluator(StdIOEvaluator): shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE + stderr=subprocess.PIPE, + preexec_fn=os.setpgrp ) success, err = self.evaluate_stdio(self.user_answer, proc, self.expected_input, diff --git a/yaksh/stdio_evaluator.py b/yaksh/stdio_evaluator.py index fa78a68..ec69851 100644 --- a/yaksh/stdio_evaluator.py +++ b/yaksh/stdio_evaluator.py @@ -2,6 +2,9 @@ from __future__ import unicode_literals # Local imports from .base_evaluator import BaseEvaluator +from .grader import TimeoutException +import os +import signal class StdIOEvaluator(BaseEvaluator): @@ -9,9 +12,13 @@ class StdIOEvaluator(BaseEvaluator): success = False ip = expected_input.replace(",", " ") encoded_input = '{0}\n'.format(ip).encode('utf-8') - user_output_bytes, output_err_bytes = proc.communicate(encoded_input) - user_output = user_output_bytes.decode('utf-8') - output_err = output_err_bytes.decode('utf-8') + try: + user_output_bytes, output_err_bytes = proc.communicate(encoded_input) + user_output = user_output_bytes.decode('utf-8') + output_err = output_err_bytes.decode('utf-8') + except TimeoutException: + os.killpg(os.getpgid(proc.pid), signal.SIGTERM) + raise expected_output = expected_output.replace("\r", "") if not expected_input: error_msg = "Expected Output is\n{0} ".\ -- cgit