Однако я столкнулся с проблемой: когда код C вызывает ошибку времени выполнения (например, деление на ноль или ошибку сегментации), код выхода_code всегда равен 0, файл error.txt пуст, а файл status.txt показывает «SUCCESS» вместо «RUNTIME_ERROR».
Dockerfile (c_runner.dockerfile):
Код: Выделить всё
FROM gcc:13.2.0
RUN apt-get update && apt-get install -y time bc && rm -rf /var/lib/apt/lists/*
RUN useradd -m runner
RUN mkdir /code && chown -R runner:runner /code
WORKDIR /code
COPY bash/run_c_code.sh /run_c_code.sh
RUN chmod +x /run_c_code.sh
USER runner
ENTRYPOINT [ "/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
# If compiled, and compile_error.txt exists, it's just a warning
if [ -f /code/compile_error.txt ]; then
echo "COMPILE_WARNING" >> /code/status.txt
fi
# Run
start_time=$(date +%s%N)
timeout 10 /usr/bin/time -f "MEM:%M" -o /code/metrics.txt /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
Код: Выделить всё
import subprocess
import tempfile
import os
temp_dir = tempfile.mkdtemp()
# Write test code with division by zero
with open(os.path.join(temp_dir, 'main.c'), 'w') as f:
f.write("""
#include
int main() {
int a = 10;
int b = 0;
int c = a / b; // Division by zero - should cause runtime error
printf("%d\\n", c);
return 0;
}
""")
# Create empty input.txt
with open(os.path.join(temp_dir, 'input.txt'), 'w') as f:
f.write("")
# Run docker
command = ['docker', 'run', '--rm', '-v', f'{temp_dir}:/code', 'seka-c-runner']
result = subprocess.run(command, capture_output=True, text=True, timeout=15)
print(f"Docker return code: {result.returncode}") # Always shows 0
print(f"Docker stdout: {result.stdout}")
print(f"Docker stderr: {result.stderr}")
# Check files
with open(os.path.join(temp_dir, 'status.txt')) as f:
print(f"Status: {f.read()}") # Shows "SUCCESS" instead of "RUNTIME_ERROR"
with open(os.path.join(temp_dir, 'error.txt')) as f:
print(f"Error output: {f.read()}") # Always empty!
Когда я запускаю код с ошибками времени выполнения (деление на ноль, ошибка сегментации, выход массива за пределы), я ожидаю:
- должен быть ненулевым (например, 136 для SIGFPE, 139 для SIGSEGV)
Код: Выделить всё
exit_code - для хранения информации об ошибке
Код: Выделить всё
error.txt - содержать «RUNTIME_ERROR»
Код: Выделить всё
status.txt
- всегда равен 0
Код: Выделить всё
exit_code - всегда пусто
Код: Выделить всё
error.txt - показывает «УСПЕХ»
Код: Выделить всё
status.txt - Результат Docker.returncode из Python также равен 0
Буду очень признателен за любые рекомендации, поскольку я изучаю, как работают системы онлайн-оценки!
Подробнее здесь: https://stackoverflow.com/questions/797 ... time-error
Мобильная версия