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()напрямую.

Другие вопросы по тегам