From 6f14ee1a7a64514b7ff6faaa7d1bcc524d6c9c7d Mon Sep 17 00:00:00 2001 From: lzkk <956449176@qq.com> Date: Tue, 26 May 2026 11:36:10 +0800 Subject: [PATCH] =?UTF-8?q?fix(infra):=20=E7=BC=96=E8=AF=91=E5=99=A8?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E9=99=90=E5=88=B6=E5=8C=85=E8=A3=85=E5=99=A8?= =?UTF-8?q?=20+=20=E6=B5=8B=E8=AF=95=E8=84=9A=E6=9C=AC=E8=B6=85=E6=97=B6?= =?UTF-8?q?=E9=98=B2=E6=8A=A4=EF=BC=8C=E9=98=B2=E6=AD=A2=20OOM=20=E9=97=AA?= =?UTF-8?q?=E9=80=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 多层防护防止编译器内存爆炸(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/ 下文件不进版本控制,不影响比赛提交。 --- 2026test.sh | 8 ++++++-- scripts/compiler-wrapper.sh | 23 +++++++++++++++++++++++ scripts/setup-compiler-wrapper.sh | 24 ++++++++++++++++++++++++ scripts/verify_asm.sh | 8 ++++++-- 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100755 scripts/compiler-wrapper.sh create mode 100644 scripts/setup-compiler-wrapper.sh diff --git a/2026test.sh b/2026test.sh index 6e1baefb..7e6ba25d 100755 --- a/2026test.sh +++ b/2026test.sh @@ -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 diff --git a/scripts/compiler-wrapper.sh b/scripts/compiler-wrapper.sh new file mode 100755 index 00000000..cf455b8d --- /dev/null +++ b/scripts/compiler-wrapper.sh @@ -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" "$@" diff --git a/scripts/setup-compiler-wrapper.sh b/scripts/setup-compiler-wrapper.sh new file mode 100644 index 00000000..95c32d55 --- /dev/null +++ b/scripts/setup-compiler-wrapper.sh @@ -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 diff --git a/scripts/verify_asm.sh b/scripts/verify_asm.sh index 0b511835..83a7770a 100755 --- a/scripts/verify_asm.sh +++ b/scripts/verify_asm.sh @@ -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 # 记录编译结束时间