mirror of
https://github.com/QingdaoU/OnlineJudge.git
synced 2024-12-28 16:12:13 +00:00
给编译器也增加超时保护
比如使用include</dev/random>就可能导致编译器卡死,增加了一个编译超时。 重命名了exception模块 整理了部分格式
This commit is contained in:
parent
d85ed0a2ec
commit
dd7fe6ee44
@ -8,9 +8,8 @@ from settings import max_running_number, lrun_gid, lrun_uid, judger_workspace
|
||||
from language import languages
|
||||
from result import result
|
||||
from compiler import compile_
|
||||
|
||||
class JudgeClientException(Exception):
|
||||
pass
|
||||
from judge_exceptions import JudgeClientException, CompileError
|
||||
from utils import parse_lrun_output
|
||||
|
||||
|
||||
# 下面这个函数作为代理访问实例变量,否则Python2会报错,是Python2的已知问题
|
||||
@ -51,21 +50,6 @@ class JudgeClient(object):
|
||||
raise JudgeClientException("Test case config file not found")
|
||||
except ValueError:
|
||||
raise JudgeClientException("Test case config file format error")
|
||||
# return {"test_case_number": 2,
|
||||
# "test_cases":
|
||||
# {
|
||||
# "1": {"input_name": "1.in",
|
||||
# "output_name": "1.out",
|
||||
# "output_md5": "b10a8db164e0754105b7a99be72e3fe5",
|
||||
# "output_size": 100},
|
||||
#
|
||||
# "2": {"input_name": "2.in",
|
||||
# "output_name": "2.out",
|
||||
# "output_md5": "3e25960a79dbc69b674cd4ec67a72c62",
|
||||
# "output_size": 100}
|
||||
# },
|
||||
# "output_total_size": 200
|
||||
# }
|
||||
|
||||
def _generate_command(self, test_case_id):
|
||||
"""
|
||||
@ -104,41 +88,8 @@ class JudgeClient(object):
|
||||
error = output[0:output_start]
|
||||
# 分离出lrun的输出
|
||||
output = output[output_start:]
|
||||
lines = output.split("\n")
|
||||
if len(lines) != 7:
|
||||
raise JudgeClientException("Lrun result parse error")
|
||||
result = {}
|
||||
# 将lrun输出的各种带下划线 不带下划线的字符串统一处理
|
||||
translate = {"MEMORY": "memory",
|
||||
"CPUTIME": "cpu_time",
|
||||
"CPU_TIME": "cpu_time",
|
||||
"REALTIME": "real_time",
|
||||
"REAL_TIME": "real_time",
|
||||
"TERMSIG": "term_sig",
|
||||
"SIGNALED": "siginaled",
|
||||
"EXITCODE": "exit_code",
|
||||
"EXCEED": "exceed"}
|
||||
for line in lines:
|
||||
name = line[:9].strip(" ")
|
||||
value = line[9:]
|
||||
if name == "MEMORY":
|
||||
result[translate[name]] = int(value)
|
||||
elif name == "CPUTIME":
|
||||
result[translate[name]] = int(float(value) * 1000)
|
||||
elif name == "REALTIME":
|
||||
result[translate[name]] = int(float(value) * 1000)
|
||||
elif name == "EXITCODE":
|
||||
result[translate[name]] = int(value)
|
||||
elif name == "TERMSIG":
|
||||
result[translate[name]] = int(value)
|
||||
elif name == "SIGNALED":
|
||||
result[translate[name]] = int(value)
|
||||
elif name == "EXCEED":
|
||||
if value == "none":
|
||||
result[translate[name]] = None
|
||||
else:
|
||||
result[translate[name]] = translate[value]
|
||||
return error, result
|
||||
|
||||
return error, parse_lrun_output(output)
|
||||
|
||||
def _compare_output(self, test_case_id):
|
||||
test_case_md5 = self._test_case_info["test_cases"][str(test_case_id)]["output_md5"]
|
||||
@ -188,7 +139,6 @@ class JudgeClient(object):
|
||||
return run_result
|
||||
|
||||
# 下面就是代码正常运行了 需要判断代码的输出是否正确
|
||||
|
||||
if self._compare_output(test_case_id):
|
||||
run_result["result"] = result["accepted"]
|
||||
else:
|
||||
@ -210,6 +160,7 @@ class JudgeClient(object):
|
||||
try:
|
||||
results.append(item.get())
|
||||
except Exception as e:
|
||||
# todo logging
|
||||
print e
|
||||
results.append({"result": result["system_error"]})
|
||||
return results
|
||||
@ -225,11 +176,10 @@ class JudgeClient(object):
|
||||
|
||||
c_src = r"""
|
||||
#include <stdio.h>
|
||||
|
||||
#include </dev/random>
|
||||
int main()
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = NULL;
|
||||
fprintf(fp, "This is testing for fprintf...\n");
|
||||
fputs("This is testing for fputs...\n", fp);
|
||||
@ -256,7 +206,7 @@ int main()
|
||||
java_src = r"""
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
11
|
||||
public class Main
|
||||
{
|
||||
public static void main(String[] args)
|
||||
@ -279,16 +229,20 @@ def judge(languege_code, source_string):
|
||||
f.write(source_string)
|
||||
f.close()
|
||||
|
||||
try:
|
||||
exe_path = compile_(languages[str(languege_code)], src_path, judger_workspace)
|
||||
except Exception as e:
|
||||
print e
|
||||
return [{"result": result["compile_error"]}]
|
||||
|
||||
client = JudgeClient(language_code=languege_code,
|
||||
exe_path=compile_(languages[str(languege_code)],
|
||||
src_path,
|
||||
judger_workspace),
|
||||
exe_path=exe_path,
|
||||
max_cpu_time=1000000,
|
||||
max_real_time=200000,
|
||||
max_memory=1000,
|
||||
test_case_dir="/var/test_cases/1/")
|
||||
print client.run()
|
||||
return client.run()
|
||||
|
||||
judge(1, c_src)
|
||||
judge(2, cpp_src)
|
||||
judge(3, java_src)
|
||||
print judge(1, c_src)
|
||||
print judge(2, cpp_src)
|
||||
print judge(3, java_src)
|
@ -1,14 +1,37 @@
|
||||
# coding=utf-8
|
||||
import commands
|
||||
|
||||
|
||||
class CompileError(Exception):
|
||||
pass
|
||||
from settings import lrun_uid, lrun_gid
|
||||
from judge_exceptions import CompileError
|
||||
from utils import parse_lrun_output
|
||||
|
||||
|
||||
def compile_(language_item, src_path, exe_path):
|
||||
command = language_item["compile_command"].format(src_path=src_path, exe_path=exe_path)
|
||||
status, output = commands.getstatusoutput(command)
|
||||
if status:
|
||||
raise CompileError(output)
|
||||
compile_command = language_item["compile_command"].format(src_path=src_path, exe_path=exe_path)
|
||||
|
||||
# 防止编译器卡死 或者 include </dev/random>等
|
||||
execute_command = "lrun" + \
|
||||
" --max-real-time 5" + \
|
||||
" --uid " + str(lrun_uid) + \
|
||||
" --gid " + str(lrun_gid) + \
|
||||
" " + \
|
||||
compile_command + \
|
||||
" 3>&2"
|
||||
status, output = commands.getstatusoutput(execute_command)
|
||||
|
||||
output_start = output.rfind("MEMORY")
|
||||
|
||||
if output_start == -1:
|
||||
raise CompileError("Error running compiler in lrun")
|
||||
|
||||
# 返回值不为0 或者 stderr中lrun的输出之前有东西
|
||||
if status or output_start:
|
||||
raise CompileError(output[0:output_start])
|
||||
|
||||
parse_result = parse_lrun_output(output)
|
||||
|
||||
if parse_result["exit_code"] or parse_result["term_sig"] or parse_result["siginaled"] or parse_result["exceed"]:
|
||||
raise CompileError("Compile error")
|
||||
|
||||
# 对于正常编译和超时等其他的错误
|
||||
return exe_path
|
||||
|
9
judge/judge_exceptions.py
Normal file
9
judge/judge_exceptions.py
Normal file
@ -0,0 +1,9 @@
|
||||
# coding=utf-8
|
||||
|
||||
|
||||
class JudgeClientException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class CompileError(Exception):
|
||||
pass
|
@ -1,7 +1,6 @@
|
||||
# coding=utf-8
|
||||
|
||||
|
||||
|
||||
languages = {
|
||||
"1": {
|
||||
"name": "c",
|
||||
|
@ -1,12 +1,14 @@
|
||||
# coding=utf-8
|
||||
|
||||
|
||||
result = {"accepted": 0,
|
||||
"runtime_error": 1,
|
||||
"time_limit_exceeded": 2,
|
||||
"memory_limit_exceeded": 3,
|
||||
"compile_error": 4,
|
||||
"format_error": 5,
|
||||
"wrong_answer": 6,
|
||||
"system_error": 7,
|
||||
"waiting": 8}
|
||||
result = {
|
||||
"accepted": 0,
|
||||
"runtime_error": 1,
|
||||
"time_limit_exceeded": 2,
|
||||
"memory_limit_exceeded": 3,
|
||||
"compile_error": 4,
|
||||
"format_error": 5,
|
||||
"wrong_answer": 6,
|
||||
"system_error": 7,
|
||||
"waiting": 8
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user