1226-TIL

그로밋·2023년 12월 27일
0

krafton jungle

목록 보기
52/58

project2 debugging (before copy,kill)

여태까지 상황

Issue #1: "Timer: #ticks" message

이쯤에서 다시 원인분석

현재 상황은 테케를 돌리면 이렇게 뜨는 상황이다.

try #1

디버깅을 해봤다.

  • 지금 나는 exec도 못들어가고 있는 상황.

  • init.c 의 main 함수를 돌고 나서 child process인 test가 돌아가는 건데 나는 main함수도 못돌고 있다.

  • 근데 죽는 지점이 매번 다르다…?🙃

  • run_actions 에서 여기서 죽음

  • 이번엔 fsutil_put()에서 죽음🙃

  • 이번엔 lock_release()에서 죽음🙃

  • 디버깅을 해봐도 죽는 지점이 계속 달라서 혼란의 연속이었다.

  • 그러다 구세주 프린트신공 마찬옥님 등장.

  • 그도 고군분투를 하다 갑자기 프린트문이 찍히면 안되는 곳에서 찍혀서 이러는것이 아니냐는 합리적의심 후 쓸모없는 프린트문 모두 제거.

    • 해당 오류가 사라져 버렸다…!🥹
    • 포기하지 않고 문제를 찾아버린 마찬옥님께 감사의 인사를…🙏

Issue #2: vm.c 에서 "threads/mmu.h" library 추가 안함

try

vm.c에서 #include "threads/mmu.h" 추가

cause

pml4관련 함수를 vm_do_claim_page()에서 pml4_set_page() 이렇게 버젓이 사용하고 있는데 라이브러리 선언을 위에 안했어서 함수 사용을 실질적으로 못하고 있었다.

Issue #3: anon_initializer()에서 return ture 안함

pintos -v -k -T 60 -m 20 --fs-disk=10 -p tests/userprog/args-single:args-single --swap-disk=4 -- -q -f run 'args-single onearg'
했을 때

try

여기서 return true;를 해주지 않았어서 추가했다.

cause

anon_initializer()에서 true를 반환해주지 않으면 vm_alloc_page_with_initializer()에서 uninit_new에서 false 값이 넘어가기 때문에 초기화가 제대로 이루어지지 않아서 해당 부분에서 문제가 생겼던 것이다.

Issue #4: switch (type) -> switch (VM_TYPE(type))

try

vm_alloc_page_with_initializer() 함수에서 스위치문 안이 의심스러웠다. 처음엔 switch (VM_TYPE(type)) 했다가 다른 사람 코드에 switch (type) 되어 있는걸 보고 바꿨던게 문제가 될 수도 있겠어서 원래코드로 바꿨다.

before :switch (type)
after : switch (VM_TYPE(type))

역시 이 문제가 맞았었다.

cause

그냥 type과 VM_TYPE(type)이 어떻게 값이 찍히는지 프린트문으로 찍어봤다.

근데 같다..?

하지만 맨끝에 7번째에는 다르다. VM_TYPE(type)은 0x1이고 type은 0x9로 찍힌다.

마지막에 그렇게 나오는 이유는 type이 유저스택의 스택에 있는 페이지라서 type이 0x9로 찍힌 것이다. 그 이유는 우리가 setup_stack()에서 스택을 할당할 때 이렇게 하기 때문에 VM_MARKER_0을 넣어주었었기 때문이다.

(VM_MARKER_0 이 1000 ->8임)

VM_TYPE()은 이렇게 define 되어있다.

0x9는 이진수로 나타내면 1001이고, 7은 이진수로 나타내면 0111
이걸 AND 연산하면 0001 이다.

따라서, VM_TYPE()으로 감싸줘야 0x1이 된다.

오늘 꽤 오랜시간 나의 에러 해결에 큰 도움을 주신 마찬옥님께 다시한번 감사의 인사를 올린다.


여기까지 했을 때 일단 fork 전까지 성공했다.
이제 copy kill 해야하고 stack growth 한 다음에 mmap하면 ...된다...하하

project2 debugging: copy,kill 구현

/* Copy supplemental page table from src to dst */
// 자식 프로세스 생성할때 spt()
bool supplemental_page_table_copy(struct supplemental_page_table *dst UNUSED,
                                  struct supplemental_page_table *src UNUSED) {
    struct hash_iterator i;
    hash_first(&i, &src->spt_hashmap);
    while (hash_next(&i)) {
        struct page *src_page =
            hash_entry(hash_cur(&i), struct page, hash_elem);
        enum vm_type type = src_page->operations->type;
        void *upage = src_page->va;
        bool writable = src_page->writable;

        // type이 uninit이면
        if (type == VM_UNINIT) {  // uninit page 생성 & 초기화
            vm_initializer *init = src_page->uninit.init;
            void *aux = src_page->uninit.aux;
            vm_alloc_page_with_initializer(VM_ANON, upage, writable, init, aux);
            continue;
        }

        // type이 uninit이 아니면
        if (!vm_alloc_page(type, upage, writable))  // uninit page 생성 & 초기화
            return false;

        // vm_claim_page으로 요청해서 매핑 & 페이지 타입에 맞게 초기화
        if (!vm_claim_page(upage)) return false;

        // 매핑된 프레임에 내용 로딩
        struct page *dst_page = spt_find_page(dst, upage);
        memcpy(dst_page->frame->kva, src_page->frame->kva, PGSIZE);
    }
    return true;
}

void hash_page_destroy(struct hash_elem *e, void *aux) {
    struct page *page = hash_entry(e, struct page, hash_elem);
    destroy(page);
    free(page);
}

/* Free the resource hold by the supplemental page table */
void supplemental_page_table_kill(struct supplemental_page_table *spt UNUSED) {
    /* TODO: Destroy all the supplemental_page_table hold by thread and
     * TODO: writeback all the modified contents to the storage. */
    hash_clear(&spt->spt_hashmap,
               hash_page_destroy);  // 해시 테이블의 모든 요소를 제거
}
profile
Work as though your strength were limitless. <S. Bernhardt>

0개의 댓글