Тестирующая система

  • Автор темы -
  • Дата начала

Гость
#1
Пишу небольшую системку для проверки решений задач учеников. Т.е. ученики посылают в систему файл на паскале/C++/Jav'e, система компилирует и выдает ответ - правильно или нет решена задача (напоминает правила олимпиад по программированию ACM).

Я знаком с большинством нынешних тестирующий систем, к сожалению они далеки от идеала или же как МГУшная системы ejudje - очень сложна в настройках.

Поэтому и решено было написать свою.


На данный момент стоят вопросы:
1. об определении есть ли в кодже ученика ассемблерная вставка.
2. как убивать выполняемое решение ученика по истечению определенного промежутка времени, т.е. если программа ученика написано не оптимально и долго работает, то завершать её автоматически и выдавать ответ что превышено время исполнения
3. Как ограничить программу по памяти, дав ей, к примеру, не более 64Мб.

На этом моменте я застрял, помогите пожалуйста...
 

vital

Больной Компом Детектед
29.01.2006
2 432
42
#3
По первому - если у вас есть исходник и известен яп, то в чем пробелема? Не думаю, что сложно найти в файле слова asm..end; и тп.
По второму - запускаете прогу, запускаете таймер. а TerminateProcess() еще никто не отменял.. Ну или WinExec('taskkill /F /IM имя.exe');
По третьему - Тут много зависит от яп.. Сходу на чистом АПИ не соображу, тут нужно с HeapSize() поколдовать.
В целом, ничего сложного.. Читайте msdn вобщем=)
ПС.
Не смог удержаться, что бы не поучить учителя=)
 

vital

Больной Компом Детектед
29.01.2006
2 432
42
#5
ЯП - язык программирования..=) Я имел ввиду, на котором прога пишется=)
 
Z

zubr

Гость
#7
По второму, я бы сделал так:
1. Запуск процесса, используя функцию CreateProcess
2. По WaitForSingleObject ждать окончания процесса или выходить по таймауту.
3. Если выход из WaitForSingleObject по таймауту, то делать TerminateProcess.
По третьему:
Вызывать по таймеру функцию GetProcessMemoryInfo, проверять параметр структуры WorkingSetSize, если превышение - делать TerminateProcess.
 

Гость
#8
Тут же возник еще вопрос:
Парсинг кода это дело простое. Но что если в файле будет обфусцированный код. Возможно ли скрытие реализации ассемблерных вставок ?

Если не возможно, то моя задача сводится к парсингу файла и поска в нем зарезервированных слов в зависимости от ЯП ? К примеру для Delphi/Pascla ищу вставки MOV, для GCC ищу __mov__ и т.д. Так ли это ???
 
Z

zubr

Гость
#10
Тут же возник еще вопрос:
Парсинг кода это дело простое. Но что если в файле будет обфусцированный код. Возможно ли скрытие реализации ассемблерных вставок ?
А что, обфускация исходного кода позволяет скрывать операторы языка?
 

vital

Больной Компом Детектед
29.01.2006
2 432
42
#11
Да и вообще, сложно представить студента который несет преподу обфусцированный исходник на проверку.. ЗАЧЕМ??
 
Z

zubr

Гость
#12
vital
А что бы преподу жизнь медом не казалась :)
 

vital

Больной Компом Детектед
29.01.2006
2 432
42
#13
zubr, имхо, принести такое преподу - это мазохизм в духе: "Здравствуйте, я хочу что бы меня вздрючили"=)
 

Гость
#14
Ну дети то сейчас идут очень талантливые, юные хакерыц так и наровят нагадить. Предполагается что дети будут сдавать решения удаленно, т.е. без присутствия учителя.

Скомпилированное их решение будет запускаться на сервере. Смысл в том чтобы не погубить сервер решением детей :)

Какие основные моменты надо при этом усмотреть ?
 
Z

zubr

Гость
#15
Я бы ограничил действия студенческих программ в пределах определенного каталога (вдруг кто то из них решит почистить диски) и определенной ветки реестра (вдруг кто то из них решит внедрить трояна).
Для этого можно воспользоваться функциями FindFirstChangeNotification, FindNextChangeNotification, FindCloseChangeNotification, для реестра RegNotifyChangeKeyValue. Еще эффективнее перехват функций обращения к файлам и реестру, так как позволит не просто констатировать произведенное действие программы, и уж потом на него реагировать, а предотвратить нехорошее действие.
 

Гость
#16
Спасибо за ответ, тут еще возник один интересный вопросик.

По условию решение ученика читает данные из файла input.txt и пишет в файл output.txt
Для каждой задачи есть набор тестов. Т.е. скомпилированному решению ученика даются по очереди тесты от 1 до N.
Есть чекер - программа для проверки данных в выходном файле. Как запустить этот чекер для всех тестов ?

Напрашивается решение для компиляции решения ученика и копирования в папку с этим решением по очереди файлов input.txt, затем выполнение скомпилированного решения и проверка с помощью чекера.

Возможно ли обойтись без такого копирования ?
 
Z

zubr

Гость
#17
Можно использовать потоки и массивы размеров (если для разных тестов размеры файлов различаются). Или массивы буферов. Каждый буфер - соответствующий ему файл input, output.
 

Гость
#18
Т.е. мой чекер пораждает процесс, который является скомпилированным решением ученика.

Можно использовать потоки и массивы размеров (если для разных тестов размеры файлов различаются). Или массивы буферов. Каждый буфер - соответствующий ему файл input, output.
Не подскажешь куда копать для реализации этого ?
Даче не знаю как вопрос в гугл или MSDN сформулировать :)
 
Z

zubr

Гость
#19
Причем здесь MSDN? Реализация зависит от языка программирования и используемых классов. К примеру, можно использовать стандартную C++ библиотеку CRT Stream, если речь о C++ Builder, то удобно использовать класс TMemoryStream. Алгоритм чекера:
1. Создать массив int - это массив размеров файлов output
2. Открыть поток для записи файлов output.
3. Для каждого файла output читать данные в буфер и записывать их в поток, в массив записывать размер файла.
Для получения данных очередного файла output:
1. По индексу массива определяем размер читаемого очередного файла output.
2. Из текущей позиции потока читаем буфер равный размеру файла.