Почему мой сценарий запуска C Docker не обнаруживает ошибку времени выполнения?Linux

Ответить
Anonymous
 Почему мой сценарий запуска C Docker не обнаруживает ошибку времени выполнения?

Сообщение Anonymous »

Я учусь воспроизводить систему онлайн-судьи с помощью Docker для запуска заявок на код C в изолированной среде. Мой сценарий bash (работающий внутри контейнера) должен обнаруживать ошибки компиляции, ошибки времени выполнения и таймауты.
Однако я столкнулся с проблемой: когда код 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" ]
Скрипт Bash (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
Код Python для выполнения:

Код: Выделить всё

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!
Проблема
Когда я запускаю код с ошибками времени выполнения (деление на ноль, ошибка сегментации, выход массива за пределы), я ожидаю: Но что происходит на самом деле: Что я делаю неправильно? Как я могу надежно обнаружить ошибки времени выполнения в коде C при запуске в этой настройке Docker? Что-то не так с тем, как я использую тайм-аут, /usr/bin/time или обработку сигналов?
Буду очень признателен за любые рекомендации, поскольку я изучаю, как работают системы онлайн-оценки!

Подробнее здесь: https://stackoverflow.com/questions/797 ... time-error
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»