基于Docker的C代码在线判题环境运行时错误无法检测的问题求助
问题分析与解决方案
你的问题主要来自三个核心问题:set -e的干扰、命令组合与重定向的逻辑错误,以及指标文件的覆盖问题。下面逐一拆解并给出修复方案:
1. 移除set -e,避免脚本提前退出
set -e会让脚本在任何命令返回非零值时立即终止,这意味着当你的C程序触发运行时错误时,timeout/time命令返回的非零退出码会直接让脚本退出,根本无法执行后续的退出码捕获和状态判断逻辑。
由于你已经在编译阶段手动处理了退出码,set -e完全是多余的,反而会破坏运行时错误的检测流程。
2. 调整命令组合与重定向,正确捕获错误信息和退出码
原来的命令没有正确区分/usr/bin/time的输出和程序自身的错误信息,导致运行时错误的提示(比如Floating point exception)无法被写入error.txt,同时time的退出码传递也出现了问题。
正确的做法是用bash -c包裹程序的运行命令,单独处理程序的输入输出重定向,让/usr/bin/time只负责收集内存指标:
timeout 10 /usr/bin/time -f "MEM:%M" -o /code/metrics.txt bash -c '/code/a.out < /code/input.txt > /code/output.txt 2> /code/error.txt'
这样,程序的标准输出写入output.txt,程序的标准错误和崩溃提示写入error.txt,time的内存统计写入metrics.txt,同时timeout会正确传递程序的退出码。
3. 修复metrics.txt的覆盖问题
你原来的脚本中,运行完time后用echo "TIME:$elapsed_time" > /code/metrics.txt会覆盖time写入的内存信息,应该改用追加模式>>:
echo "TIME:$elapsed_time" >> /code/metrics.txt
修改后的完整run_c_code.sh脚本
#!/bin/bash # 移除set -e,避免提前退出 gcc /code/main.c -o /code/a.out 2> /code/compile_error.txt compile_exit=$? if [ $compile_exit -ne 0 ]; then echo "COMPILE_ERROR" > /code/status.txt exit $compile_exit fi # 如果编译完成但compile_error.txt非空,判定为警告 if [ -s /code/compile_error.txt ]; then echo "COMPILE_WARNING" > /code/status.txt fi # 运行代码 start_time=$(date +%s%N) timeout 10 /usr/bin/time -f "MEM:%M" -o /code/metrics.txt bash -c '/code/a.out < /code/input.txt > /code/output.txt 2> /code/error.txt' exit_code=$? echo "E_CODE=$exit_code" > /code/status_code.txt end_time=$(date +%s%N) elapsed_time=$(( (end_time-start_time) / 1000000)) echo "TIME:$elapsed_time" >> /code/metrics.txt # 改为追加模式 if [ $exit_code -eq 124 ]; then echo "TIMEOUT" > /code/status.txt exit 124 elif [ $exit_code -ne 0 ]; then echo "RUNTIME_ERROR" > /code/status.txt exit $exit_code else echo "SUCCESS" > /code/status.txt fi
额外优化点
- 将
if [ -f /code/compile_error.txt ]改为if [ -s /code/compile_error.txt ]:检查文件是否非空,避免gcc输出空内容(无警告无错误)时误判为编译警告。 - 保留
USER runner的设置:沙箱环境使用非root用户运行代码是正确的安全实践,无需修改。
测试验证
重新构建Docker镜像后运行你的Python测试代码,现在应该能得到预期结果:
exit_code为136(对应除零错误的SIGFPE信号)error.txt包含Floating point exception的错误信息status.txt显示RUNTIME_ERROR- Python中的
result.returncode为136
内容的提问来源于stack exchange,提问作者Papazy
相关产品推荐
相关产品推荐

