Pintos - UserProg все тесты не пройдены is_kernel_vaddr()
Я делаю проект Pintos на стороне, чтобы узнать больше об операционных системах. Сначала у меня были проблемы с devops, потому что он не очень хорошо работал с каплей Ubuntu 18.04. Я теперь запускаю это на образе VirtualBox, который UCCS говорит студентам загрузить для pintos.
Я закончил проект 1 и начал планировать свое решение для проекта 2. Следуя инструкциям по созданию файла, который я запустил
pintos-mkdisk filesys.dsk --filesys-size=2
pintos -- -f -q
но получаю ошибку
Kernel PANIC at ../../threads/vaddr.h:87 in vtop(): assertion
`is_kernel_vaddr (vaddr)' failed.
Затем я попытался запустить make check (все тесты). Все они терпят неудачу по одной и той же причине.
Я что-то пропустил? Есть ли что-то, что мне нужно реализовать, чтобы это исправить? Я перечитал инструкцию и ничего не увидел?
Буду признателен за помощь! Спасибо
2 ответа
У меня была похожая проблема. Мой код для Project 1 работал нормально, но я не смог отформатировать файловую систему для Project 2.
Ошибка для меня произошла из следующей цепочки вызовов:
thread_init()
->... -> thread_schedule_tail()
-> process_activate()
-> pagedir_activate()
-> vtop()
Проблема в том, что init_page_dir
все еще NULL, когда pagedir_activate()
называется. init_page_dir
должен был быть инициализирован в paging_init()
но это называется после thread_init()
,
Основной причиной было то, что мой планировщик вызывался слишком рано, то есть до вызова thread_start()
, Причиной моей проблемы было то, что я встроил вызов thread_yield()
по завершении каждого звонка lock_release()
что имеет смысл с точки зрения приоритетного пожертвования. К сожалению, блокировки используются до того, как планировщик будет готов! Чтобы это исправить, я установил флаг threading_started
который залог в первой строке моего thread_block()
а также thread_yield()
функционирует, если thread_start()
еще не был вызван.
Удачи!
В дополнение к ответу Чарльза Селерье, это сработало для меня.
Определятьthread_try_yield
такой как
void thread_try_yield(void) {
if (!list_empty(&ready_list) && thread_current() != idle_thread)
thread_yield();
}
и позвони ему, а не позвониthread_yield()
напрямую.