async def compile(self, compile_config, src_path, output_dir): command = compile_config["compile_command"] exe_path = os.path.join(output_dir, compile_config["exe_name"]) command = command.format(src_path=src_path, exe_dir=output_dir, exe_path=exe_path) compiler_out = os.path.join(output_dir, "compiler.out") _command = command.split(" ") os.chdir(output_dir) result = await kernel.run(max_cpu_time=compile_config["max_cpu_time"], max_real_time=compile_config["max_real_time"], max_memory=compile_config["max_memory"], max_stack=128 * 1024 * 1024, max_output_size=1024 * 1024, max_process_number=kernel.UNLIMITED, exe_path=_command[0], input_path=src_path, output_path=compiler_out, error_path=compiler_out, args=_command[1::], env=["PATH=" + os.getenv("PATH")], log_path=COMPILER_LOG_PATH, seccomp_rule_name=None, uid=COMPILER_USER_UID, gid=COMPILER_GROUP_GID) if result["result"] != kernel.RESULT_SUCCESS: if os.path.exists(compiler_out): with open(compiler_out, encoding="utf-8") as f: error = f.read().strip() os.remove(compiler_out) if error: raise CompileError(error) raise CompileError("Compiler runtime error, info: %s" % json.dumps(result)) os.remove(compiler_out) return exe_path
def __call__(self) -> None: os.chdir(self.base_dir) compiler_out = "compiler_output.log" _command = self.command.split(" ") result = _judger.run( max_cpu_time=self._max_cpu_time, max_real_time=self._max_real_time, max_memory=self._max_memory, max_stack=256 * 1024 * 1024, max_output_size=-1, max_process_number=-1, exe_path=_command[0], # /dev/null is best, but in some system, this will call ioctl system call input_path='/dev/null', output_path=compiler_out, error_path=compiler_out, args=_command[1::], env=default_env, log_path='compiler.log', seccomp_rule_name=None, uid=0, gid=0) if result["result"] != _judger.RESULT_SUCCESS: if os.path.exists(compiler_out): with open(compiler_out, encoding="utf-8") as f: error = f.read().strip() if error: raise CompileError(error) logging.warning(f"CE {result}") raise CompileError("Compiler runtime error, info: System Broken")
def compile(self, compile_config, src_path, output_dir): #通过编译配置获取编译命令 command = compile_config["compile_command"] #拼接配置执行文件路径,output_dir就是submission_dir exe_path = os.path.join(output_dir, compile_config["exe_name"]) #编译命令格式化,格式化路径在配置文件里面 command = command.format(src_path=src_path, exe_dir=output_dir, exe_path=exe_path) #编译完成文件输出路径 compiler_out = os.path.join(output_dir, "compiler.out") #按照空格将编译命令分割成块 _command = command.split(" ") #转到编译输出文件路径 os.chdir(output_dir) #调用评判机Judger模块进行编译,也就是说编译也是要经过评判机的,因为编译本身就是一个执行文件的过程, #用户的可执行代码在另外一个文件judge-client中处理。 result = _judger.run( max_cpu_time=compile_config["max_cpu_time"], max_real_time=compile_config["max_real_time"], max_memory=compile_config["max_memory"], max_stack=128 * 1024 * 1024, max_output_size=1024 * 1024, max_process_number=_judger.UNLIMITED, #-1 #编译命令空格分割的第一个文件,这里的exe_path已经更改成编译器的路径,不是上面的exe_path了 exe_path=_command[0], # 使用为文件/dev/null是最好的,但在某些系统中,这将调用ioctl system call input_path=src_path, output_path=compiler_out, error_path=compiler_out, #从第一个开始读取参数 args=_command[1::], #设置运行环境 env=["PATH=" + os.getenv("PATH")], log_path=COMPILER_LOG_PATH, #这里不设置安全计算规则是因为编译的执行文件第一个都是系统的编译器,本身运行就对系统无害 #唯一出现的可能就是编译错误 seccomp_rule_name=None, uid=COMPILER_USER_UID, gid=COMPILER_GROUP_GID) # 如果编译异常,结果不相等,并且编译输出文件存在,那么打开文件并设置编译错误信息,最后删除此文件 # 只会出现编译错误,不可能出现其他错误。 if result["result"] != _judger.RESULT_SUCCESS: if os.path.exists(compiler_out): with open(compiler_out, encoding="utf-8") as f: error = f.read().strip() os.remove(compiler_out) # 错误不空,抛出错误 if error: raise CompileError(error) #抛出编译错误信息 raise CompileError("Compiler runtime error, info: %s" % json.dumps(result)) else: #编译通过,删除编译输出文件,返回编译用户的代码后执行文件路径 os.remove(compiler_out) return exe_path
def compile(self, compile_config: dict, src_path, output_dir): command = compile_config["compile_command"] exe_path = os.path.join(output_dir, compile_config["exe_name"]) command = command.format(src_path=src_path, exe_dir=output_dir, exe_path=exe_path) compiler_out = os.path.join(output_dir, "compiler.out") _command = command.split(" ") env = ["PATH=" + os.getenv("PATH")] if not compile_config.get("compile_env") == None: env.extend(compile_config.get("compile_env")) os.chdir(output_dir) result = _judger.run( max_cpu_time=compile_config["max_cpu_time"], max_real_time=compile_config["max_real_time"], max_memory=compile_config["max_memory"], max_stack=128 * 1024 * 1024, max_output_size=1024 * 1024, max_process_number=_judger.UNLIMITED, exe_path=_command[0], # /dev/null is best, but in some system, this will call ioctl system call input_path=src_path, output_path=compiler_out, error_path=compiler_out, args=_command[1::], env=env, log_path=COMPILER_LOG_PATH, seccomp_rule_name=None, uid=COMPILER_USER_UID, gid=COMPILER_GROUP_GID) if result["result"] != _judger.RESULT_SUCCESS: if os.path.exists(compiler_out): with open(compiler_out, encoding="utf-8") as f: error = f.read().strip() os.remove(compiler_out) compile_conf = json.dumps(compile_config) environment = json.dumps(env) if error: raise CompileError( "Compiler Error.\nConfig: %s\nEnv: %s\nstdout:\n%s" % (compile_conf, environment, error)) raise CompileError( "Compiler runtime error\nConfig: %s\nEnv: %s\ninfo: %s" % (compile_conf, environment, json.dumps(result))) else: os.remove(compiler_out) return exe_path
def compile(self): if not verify(self.box_id): raise SandboxError('sandbox id should in range 0~99.') # except meta file other are all relative path output_dir = os.path.join(JUDGE_DEFAULT_PATH, self.box_id, 'box') meta_file = os.path.join(output_dir, 'compiler.meta') compiler_out = 'compiler.out' command = self.compile_config["compile_command"] group_memory = self.compile_config.get('group_memory') command = command.format(src_name=self.compile_config['src_name'], exe_name=self.compile_config['exe_name']) compiler = Runner( max_cpu_time=self.compile_config['max_cpu_time'], max_real_time=self.compile_config['max_real_time'], max_memory=self.compile_config['max_memory'], box_id=self.box_id, max_output_size=1024, # 1M max_process_number=-1, input_file=None, output_file=compiler_out, error_file=compiler_out, meta_file=meta_file, run_args=command, group_memory=True if group_memory else False, ) compiler.run() if compiler.result['status'] == Runner.RESULT['success']: return self.compile_config['exe_name'] else: info = compiler.result['info']['error'] info = str(info).replace('"', "'") raise CompileError(info)
def compile(self, compile_config, src_path, output_dir): command = compile_config["compile_command"] exe_path = os.path.join(output_dir, compile_config["exe_name"]) command = command.format(src_path=src_path, exe_dir=output_dir, exe_path=exe_path) # temp solution. command = command.replace(' -std=c++14','') compiler_out = os.path.join(output_dir, "compiler.out") _command = command.split(" ") os.chdir(output_dir) env = compile_config.get("env", []) env.append("PATH=" + os.getenv("PATH")) logger.info('env:%s exe_path:%s args:%s', env, _command[0], _command[1::] ) result = _judger.run(max_cpu_time=compile_config["max_cpu_time"], max_real_time=compile_config["max_real_time"], max_memory=compile_config["max_memory"], max_stack=128 * 1024 * 1024, max_output_size=20 * 1024 * 1024, max_process_number=_judger.UNLIMITED, exe_path=_command[0], # /dev/null is best, but in some system, this will call ioctl system call input_path=src_path, output_path=compiler_out, error_path=compiler_out, args=_command[1::], env=env, log_path=COMPILER_LOG_PATH, seccomp_rule_name=None, uid=COMPILER_USER_UID, gid=COMPILER_GROUP_GID) logger.info('compiler_out file:' + compiler_out) logger.info('judger_result:%s', result) if result["result"] != _judger.RESULT_SUCCESS: if os.path.exists(compiler_out): with open(compiler_out, encoding="utf-8") as f: error = f.read().strip() #os.remove(compiler_out) logger.info('compiler out:' + error) if error: raise CompileError(error) raise CompileError("Compiler runtime error, info: %s" % json.dumps(result)) else: #os.remove(compiler_out) return exe_path
def compile(compile_config, src_path, output_dir): command = compile_config["compile_command"] exe_path = os.path.join(output_dir, compile_config["exe_name"]) command = command.format(src_path=src_path, exe_dir=output_dir, exe_path=exe_path) compiler_out = os.path.join(output_dir, "compiler.out") _command = command.split(" ") os.chdir(output_dir) result = _judger.run( max_cpu_time=compile_config["max_cpu_time"], max_real_time=compile_config["max_cpu_time"] * 3, max_memory=compile_config["max_memory"], max_stack=128 * 1024 * 1024, max_output_size=128 * 1024 * 1024, max_process_number=_judger.UNLIMITED, exe_path=_command[0], # /dev/null is best, but in some system, this will call ioctl system call input_path=src_path, output_path=compiler_out, error_path=compiler_out, args=_command[1::], env=["PATH=" + os.getenv("PATH")], log_path=COMPILER_LOG_PATH, seccomp_rule_name=None, uid=COMPILER_USER_UID, gid=COMPILER_GROUP_GID) # print("[COMPILE RESULT]") # print(json.dumps(result, indent=4)) if result["result"] != _judger.RESULT_SUCCESS: if os.path.exists(compiler_out): with open(compiler_out, encoding="utf-8") as f: error = f.read().strip() os.remove(compiler_out) if error: raise CompileError(error) raise CompileError("Compiler runtime error, info: %s" % json.dumps(result)) else: os.remove(compiler_out) return exe_path