fix(infra): 编译器资源限制包装器 + 测试脚本超时防护,防止 OOM 闪退

多层防护防止编译器内存爆炸(mm1.sy 9.9GB)触发 OOM Killer 导致终端闪退:
- compiler-wrapper.sh: 通用包装器,ulimit -v 12GB + timeout 300s
- setup-compiler-wrapper.sh: cmake 构建后恢复包装器
- 2026test.sh, verify_asm.sh: 自动检测包装器 + 编译器调用加 timeout

build/ 下文件不进版本控制,不影响比赛提交。
lzk
lzkk 1 week ago
parent 5300e2c1ec
commit 6f14ee1a7a

@ -12,6 +12,10 @@ NC='\033[0m'
TEST_ROOT="./2026test"
OUTPUT_DIR="./2026test_results"
COMPILER="./build/bin/compiler"
# 本地开发:自动使用包装器限制内存,防止编译器 bug 触发 OOM
if [[ -x "./scripts/compiler-wrapper.sh" ]]; then
COMPILER="./scripts/compiler-wrapper.sh"
fi
VERIFY_SCRIPT="./scripts/verify_asm.sh"
TIME_ORI_FILE="$OUTPUT_DIR/time_ori.txt"
TIME_OPT_FILE="$OUTPUT_DIR/time_opt.txt"
@ -476,9 +480,9 @@ for file in "${ALL_CASES[@]}"; do
set +e
if [[ "$OPTIMIZE" == "true" ]]; then
"$COMPILER" -O --emit-asm "$file" > "$asm_file" 2>/dev/null
timeout --signal=KILL "$((TIMEOUT_MS / 1000))" "$COMPILER" -O --emit-asm "$file" > "$asm_file" 2>/dev/null
else
"$COMPILER" --emit-asm "$file" > "$asm_file" 2>/dev/null
timeout --signal=KILL "$((TIMEOUT_MS / 1000))" "$COMPILER" --emit-asm "$file" > "$asm_file" 2>/dev/null
fi
compile_code=$?
set -e

@ -0,0 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail
# === 编译器资源限制包装器 ===
# 比赛提交不包含此机制
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
REAL="$PROJECT_ROOT/build/bin/compiler.real"
# 如果 build/bin/compiler.real 不存在,尝试 build/bin/compiler
if [[ ! -x "$REAL" ]]; then
if [[ -x "$PROJECT_ROOT/build/bin/compiler" ]] && file "$PROJECT_ROOT/build/bin/compiler" | grep -q 'ELF'; then
REAL="$PROJECT_ROOT/build/bin/compiler"
fi
fi
if [[ ! -x "$REAL" ]]; then
echo "错误: 编译器二进制不存在" >&2
echo "提示: 运行 cmake --build build 重新构建" >&2
exit 1
fi
ulimit -S -v 12582912 2>/dev/null || true
exec timeout --signal=KILL 300 "$REAL" "$@"

@ -0,0 +1,24 @@
#!/usr/bin/env bash
# 编译器包装器恢复脚本 — 每次 cmake --build 后运行此脚本
# cmake 构建会覆盖 build/bin/compiler 为 ELF 二进制,
# 此脚本将其重命名为 compiler.real 并安装资源限制包装器
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
BIN_DIR="$SCRIPT_DIR/../build/bin"
COMPILER_BIN="$BIN_DIR/compiler"
if [[ ! -f "$COMPILER_BIN" ]]; then
echo "错误: $COMPILER_BIN 不存在,请先构建" >&2
exit 1
fi
if file "$COMPILER_BIN" | grep -q 'ELF'; then
echo "检测到 ELF 二进制,安装资源限制包装器..."
mv "$COMPILER_BIN" "$BIN_DIR/compiler.real"
cp "$SCRIPT_DIR/compiler-wrapper.sh" "$COMPILER_BIN"
chmod +x "$COMPILER_BIN"
echo "完成: $COMPILER_BIN 现在是资源限制包装器"
else
echo "包装器已存在,跳过"
fi

@ -35,6 +35,10 @@ if [[ ! -f "$input" ]]; then
fi
compiler="./build/bin/compiler"
# 本地开发:自动使用包装器限制内存
if [[ -x "./scripts/compiler-wrapper.sh" ]]; then
compiler="./scripts/compiler-wrapper.sh"
fi
if [[ ! -x "$compiler" ]]; then
echo "未找到编译器: $compiler ,请先构建。" >&2
exit 1
@ -131,9 +135,9 @@ expected_file="$input_dir/$stem.out"
compile_start=$(get_timestamp_ms)
if [[ "$optimize" == true ]]; then
"$compiler" -O --emit-asm "$input" > "$asm_file"
timeout --signal=KILL 300 "$compiler" -O --emit-asm "$input" > "$asm_file"
else
"$compiler" --emit-asm "$input" > "$asm_file"
timeout --signal=KILL 300 "$compiler" --emit-asm "$input" > "$asm_file"
fi
# 记录编译结束时间

Loading…
Cancel
Save