Repository navigation
Judge Sandbox
dxx114514-stack edited this page Oct 5, 2026
·
4 revisions
提交代码 → 限流/提交锁检查 → 进入评测队列 → 编译 → 逐测试点运行 → 计分
↘ WebSocket 实时推送状态(pending → compiling → running → 结果)
-
评测并发:
config/judge.txt缺失时MAX_THREADS默认(CPU 核数 + 1) / 2(最小 1),可由config/judge.txt的MAX_THREADS=或环境变量NoldOJ_JUDGE_THREADS覆盖。 -
崩溃恢复:启动时
recoverInterruptedSubmissions()把中断的提交置为系统错误;IDE 残留的pending/pending_review/compiling/running中间态同步收敛,避免永远显示「运行中」。 - 限流:提交 10 次/分钟、IDE 运行 20 次/分钟(可调,见 配置说明)。
- 提交锁:存在未完成提交时禁止再次提交,超管及特权用户可豁免。
主要支持平台为 Windows,两种执行模式:
| 模式 | 条件 | 隔离手段 |
|---|---|---|
| 安全沙箱模式(推荐) |
sandbox/sandbox_runner.exe 存在 |
Job Object(内存/CPU/进程树限制)+ 受限令牌 + 低完整性级别(Low IL),文件 IO 题目模式降权写入 |
| 传统回退模式 | 非 Windows 平台;或显式 NoldOJ_ALLOW_NO_SANDBOX=1 且运行器缺失(Windows 默认 fail-closed 拒绝判题) |
直接 spawn 编译产物;Windows 每 150ms 用 tasklist 轮询内存、超限即杀,另有超时 kill 与 64KB 输出限制兜底;非 Windows 仅超时与输出限制 |
-
start.bat每次启动都会从sandbox/sandbox_runner.cpp重新编译sandbox_runner.exe(需要 g++;编译不可用时沿用已有 exe,仍无 exe 则判题 fail-closed);异常发生时启动日志会明确 WARN。 - 沙箱模式下内存峰值由 Job Object 测量;回退模式在 Windows 上由
tasklist轮询测量内存(峰值超限即终止,结果标记MEMORY_LIMIT)。显示 0KB 仅出现在非 Windows 回退或tasklist无采样(如进程过早退出)时,不代表回退模式不测内存。 - Windows 缺
sandbox_runner.exe时默认 fail-closed 拒绝判题;仅显式设NoldOJ_ALLOW_NO_SANDBOX=1(不安全,仅限本地开发)才回退传统模式(旧开关NoldOJ_REQUIRE_RUNNER=1行为与默认一致,可不再设置)。其余诊断开关(NoldOJ_NO_APPCONTAINER、NoldOJ_FORCE_CONTAINER、NoldOJ_EXEC_MODE、NoldOJ_NO_LOWIL、NoldOJ_NO_RELABEL、NoldOJ_ROOT、NoldOJ_SANDBOX_VERBOSE)见docs/support.html的「沙箱环境变量」表。 - Linux(如 CI)总是走传统回退模式;运行命令由语言配置的
runUnix决定。 - Windows 下超时通过
taskkill /F /T异步杀进程树,其他平台用SIGKILL。 - 单次运行最大输出
64KB(sandbox.maxOutputSize),工作目录为系统临时目录,判题后自动清理。
- AI 代码安全审查(可选):提交/IDE 运行前经 LLM 审查,含 14 种提示词注入模式检测,异步执行不阻塞响应;恶意代码可自动封禁。
-
代码长度限制:128KB(
CODE_LENGTH_LIMIT)。 - 封禁链路:封禁后 Access Token 与 Refresh Token 全拦截,并支持强制登出时间戳。
- 注册限流:单 IP 每小时 1 次注册。
- 编译/运行命令与参数经模板替换后不经 shell 拆词执行,杜绝参数注入;多文件 C++ 编译走参数数组直传;单次提交文件数上限 64(
executor.js的MAX_FILES)。
-
测试点:
.in/.out成对上传(手传、ZIP、批量接口均可)。SPJ 特殊测试脚本由独立 node 子进程在vm沙箱中执行(1 秒超时、阻断require/process),不经过sandbox_runner.exe。 -
submit_answer题型:考生提交纯答案(answer_data),判题时直接与预期输出比对,无需编译运行。 -
输出比较模式:测试点
compare_mode支持text_strict/text_relaxed/real_number(配real_number_tolerance容差)与spj(特殊评测)。 -
子任务(Subtask):测试点分组,组间可配置依赖与聚合策略(
sum求和 /min取最小 /max取最大 /min_score最低分 /max_time最短时间 /custom自定义)。 - 题目级/组级计分脚本:自定义评分逻辑。
-
语句以
;分隔;变量以@开头(@total_score、@status1)。 - 运算:算术
+ - * / %,位运算与逻辑运算and or not xor,比较== != >= <= > <;条件表达式支持括号。 - 内置函数:
min(a, b)、max(a, b)、abs(a)。 - 条件语句:
if 条件; then 语句; else 语句; fi -
常量:测试点
AC(1)、WA(2)、TLE(3)、MLE(4);Subtask/整题AC(1)、UNAC(2)。 -
传入变量:
@statusX、@scoreX、@timeX、@memoryX(X 为测试点/Subtask ID)。 -
需定义变量:
@total_score、@final_status、@final_time、@final_memory。
示例:
if (@status4==AC) and (@status3==AC or @status5==AC); then
@total_score = 30;
@final_status = AC;
@final_time = @time4;
@final_memory = @memory4;
else
@total_score = 0;
@final_status = UNAC;
fi
@total_score = min(@score1 + @score2, 30);
@final_time = max(@time1, @time2);
默认语言(backend/database/db.js 初始化):
| 语言 | 编译命令 | 运行命令 |
|---|---|---|
| C | gcc -O2 -Wall -o "{exe}" "{src}" |
"{exe}" |
| C++ | g++ -O2 -Wall -std=c++17 -o "{exe}" "{src}" |
"{exe}" |
| Python 3 | — | python "{src}" |
| Java | javac "{src}" -d "{workdir}" |
java -cp "{workdir}" Main |
| JavaScript | — | node "{src}" |
占位符:{src} 源文件、{exe} 可执行文件(Windows 下自动补 .exe)、{workdir} 工作目录。新增/修改语言:超级管理员在「语言」管理页面填写即可(存数据库、热生效)。
NoldOJ · Windows 在线评测系统 · MIT License