WEEK 13 PintOS TIL(6월7일 토요일 ~ 6월8일 일요일)

Devkty·2025년 6월 9일

6월 7일 토요일

참고로 이번 TIL에는 놀러간 이야기와 사진들이 많습니다!

[목표]
stack growth를 구현하고 관련 테스트 케이스를 통과해봅니다. (진행중)
놀러가기때문에, 가서 시간 남는대로 티스토리 정리해봅니다.

벨로그와 노션 먼저 정리하기. 틈틈히 코드 관련 해서 정리하기.
밀린 티스토리정리하기!!!!!!! (너무 밀림)

10:00 ~ 10:45

출근해서 잤음… 5시에 여파가…

10:45 ~ 12:00

stack growth를 구현해봅니다.

vm_try_handle_fault

먼저 vm_try_handle_fault 함수를 수정해줘야한다. 왜냐하면 스택 자동확장이 필요한 시기에 확장을 시도해야하기 때문입니다. 즉, 스택 증가를 식별해줍니다. 케이스1과 2가 정상적으로 실행된다면 페이지 적재를 수행합니다.

/* Return true on success */
// 성공 시 true를 반환합니다.
bool
vm_try_handle_fault (struct intr_frame *f UNUSED, void *addr UNUSED,
		bool user UNUSED, bool write UNUSED, bool not_present UNUSED) {
	struct supplemental_page_table *spt UNUSED = &thread_current ()->spt;
	struct page *page = spt_find_page(spt, addr);  /* valid address인지 확인 */
 
	void *va = pg_round_down(addr);  // 주소를 정렬에 맞춰준다.
	/* TODO: Validate the fault */
	/* TODO: Your code goes here */

	// case 1: page가 없음 → stack growth 고려
	// 스택 자동확장이 필요한 상황일 때, vm_stack_growth 함수로 확장해줍니다.
	if(page == NULL) {
		// 유저 모드에서 발생한 폴트만 처리, 유저 스택 포인터 바로 아래에 접근할 시 허용, 접근한 주소가 전체 유저 스택 범위 안에 있는지 확인. -> 모든 조건일시 스택 확장
		// 스택확장 부분이 왜 if문에 있는지 의아할 수 있는데, 이는 스택확장이 무조건 성공하지 않으므로 실패시 spt_find_page를 실행하지 않도록 방지한다.
		if (user && addr >= f->rsp - 32 && addr < USER_STACK && vm_stack_growth(addr)) {
			page = spt_find_page(spt, addr);   // addr이 현재 스택 영역 바로 아래에 접근한 경우에만 새 페이지를 할당
		}
		else
			return false;
	}

	// case 2: 접근 권한 확인 (write 접근인데 read-only면 실패)
	if (write && !page->writable)  // 쓰기 접근인데 페이지가 읽기 전용이라면, false 반환
    	return false;
	
	// 페이지 적재 (uninit이든 아니든 모두 처리)
	return vm_do_claim_page (page);
}

vm_stack_growth 를 구현하다가 가족행사로 인해 나왔습니다.

23:30 ~ 02:00

모든 내용 티스토리와 벨로그 동기화 완료.

vm_stack_growth

놀랍게도 다음과 같이 구현하면 테스트 케이스가 통과된다. 아마 페이지 폴트에서 넘기는 부분에서 미리 구현해서 그런 것 같다. 이유는 정글에서 적어보겠다.

tests/vm/pt-grow-stack 와 tests/vm/pt-big-stk-obj 두가지 테스트 케이스이다.

/* Growing the stack. */
// 스택을 키웁니다.
static bool
vm_stack_growth (void *addr UNUSED) {
	struct thread *t = thread_current();
	void *va = pg_round_down(addr);  // 주소를 정렬에 맞춰준다.

	// 실제로 할당 요청
    return vm_alloc_page(VM_ANON | VM_MARKER_0, va, true);
}
pass tests/userprog/args-none
pass tests/userprog/args-single
pass tests/userprog/args-multiple
pass tests/userprog/args-many
pass tests/userprog/args-dbl-space
pass tests/userprog/halt
pass tests/userprog/exit
pass tests/userprog/create-normal
pass tests/userprog/create-empty
pass tests/userprog/create-null
pass tests/userprog/create-bad-ptr
pass tests/userprog/create-long
pass tests/userprog/create-exists
pass tests/userprog/create-bound
pass tests/userprog/open-normal
pass tests/userprog/open-missing
pass tests/userprog/open-boundary
pass tests/userprog/open-empty
pass tests/userprog/open-null
pass tests/userprog/open-bad-ptr
pass tests/userprog/open-twice
pass tests/userprog/close-normal
pass tests/userprog/close-twice
pass tests/userprog/close-bad-fd
pass tests/userprog/read-normal
pass tests/userprog/read-bad-ptr
pass tests/userprog/read-boundary
pass tests/userprog/read-zero
pass tests/userprog/read-stdout
pass tests/userprog/read-bad-fd
pass tests/userprog/write-normal
pass tests/userprog/write-bad-ptr
pass tests/userprog/write-boundary
pass tests/userprog/write-zero
pass tests/userprog/write-stdin
pass tests/userprog/write-bad-fd
pass tests/userprog/fork-once
pass tests/userprog/fork-multiple
pass tests/userprog/fork-recursive
FAIL tests/userprog/fork-read
FAIL tests/userprog/fork-close
FAIL tests/userprog/fork-boundary
pass tests/userprog/exec-once
pass tests/userprog/exec-arg
FAIL tests/userprog/exec-boundary
pass tests/userprog/exec-missing
pass tests/userprog/exec-bad-ptr
FAIL tests/userprog/exec-read
pass tests/userprog/wait-simple
pass tests/userprog/wait-twice
pass tests/userprog/wait-killed
pass tests/userprog/wait-bad-pid
pass tests/userprog/multi-recurse
pass tests/userprog/multi-child-fd
pass tests/userprog/rox-simple
pass tests/userprog/rox-child
pass tests/userprog/rox-multichild
pass tests/userprog/bad-read
pass tests/userprog/bad-write
pass tests/userprog/bad-read2
pass tests/userprog/bad-write2
pass tests/userprog/bad-jump
pass tests/userprog/bad-jump2
pass tests/vm/pt-grow-stack
pass tests/vm/pt-grow-bad
pass tests/vm/pt-big-stk-obj
pass tests/vm/pt-bad-addr
pass tests/vm/pt-bad-read
pass tests/vm/pt-write-code
FAIL tests/vm/pt-write-code2
FAIL tests/vm/pt-grow-stk-sc
pass tests/vm/page-linear
pass tests/vm/page-parallel
FAIL tests/vm/page-merge-seq
FAIL tests/vm/page-merge-par
FAIL tests/vm/page-merge-stk
FAIL tests/vm/page-merge-mm
pass tests/vm/page-shuffle
FAIL tests/vm/mmap-read
FAIL tests/vm/mmap-close
FAIL tests/vm/mmap-unmap
FAIL tests/vm/mmap-overlap
FAIL tests/vm/mmap-twice
FAIL tests/vm/mmap-write
FAIL tests/vm/mmap-ro
FAIL tests/vm/mmap-exit
FAIL tests/vm/mmap-shuffle
pass tests/vm/mmap-bad-fd
FAIL tests/vm/mmap-clean
FAIL tests/vm/mmap-inherit
FAIL tests/vm/mmap-misalign
FAIL tests/vm/mmap-null
FAIL tests/vm/mmap-over-code
FAIL tests/vm/mmap-over-data
FAIL tests/vm/mmap-over-stk
FAIL tests/vm/mmap-remove
pass tests/vm/mmap-zero
pass tests/vm/mmap-bad-fd2
pass tests/vm/mmap-bad-fd3
pass tests/vm/mmap-zero-len
FAIL tests/vm/mmap-off
FAIL tests/vm/mmap-bad-off
FAIL tests/vm/mmap-kernel
FAIL tests/vm/lazy-file
pass tests/vm/lazy-anon
FAIL tests/vm/swap-file
FAIL tests/vm/swap-anon
FAIL tests/vm/swap-iter
FAIL tests/vm/swap-fork
pass tests/filesys/base/lg-create
pass tests/filesys/base/lg-full
pass tests/filesys/base/lg-random
pass tests/filesys/base/lg-seq-block
pass tests/filesys/base/lg-seq-random
pass tests/filesys/base/sm-create
pass tests/filesys/base/sm-full
pass tests/filesys/base/sm-random
pass tests/filesys/base/sm-seq-block
pass tests/filesys/base/sm-seq-random
FAIL tests/filesys/base/syn-read
pass tests/filesys/base/syn-remove
FAIL tests/filesys/base/syn-write
pass tests/threads/alarm-single
pass tests/threads/alarm-multiple
pass tests/threads/alarm-simultaneous
pass tests/threads/alarm-priority
pass tests/threads/alarm-zero
pass tests/threads/alarm-negative
pass tests/threads/priority-change
pass tests/threads/priority-donate-one
pass tests/threads/priority-donate-multiple
pass tests/threads/priority-donate-multiple2
pass tests/threads/priority-donate-nest
pass tests/threads/priority-donate-sema
pass tests/threads/priority-donate-lower
pass tests/threads/priority-fifo
pass tests/threads/priority-preempt
pass tests/threads/priority-sema
pass tests/threads/priority-condvar
pass tests/threads/priority-donate-chain
FAIL tests/vm/cow/cow-simple
39 of 141 tests failed.

이하 영덕에서 찍은 사진들





6월 8일 일요일

[목표]
stack growth를 구현하고 관련 테스트 케이스를 통과해봅니다.

이하 판교에서 찍은 사진들



21:00 ~ 22:00

팔순잔치를 마치고 복귀했다.
새로운 시놀로지 패키지가 있어서 시놀로지에 들어가 패키지를 살펴보았다.
예전에 대학교때 진행한 프로젝트가 리포지트리에 없어서 정글에서 배운대로 클론해서 내 리포지트리에 추가했다.

22:00 ~ 02:40

스택 그로우를 어제 완성했지만, 이해하지 못해 이해하며 통과하지 못한 테스트 케이스를 확인해보고 있다.
각각의 결과값을 확인하면서 부족한 부분을 수정해보고 있다.

FAIL tests/userprog/fork-read
FAIL tests/userprog/fork-close
FAIL tests/userprog/fork-boundary
FAIL tests/userprog/exec-boundary
FAIL tests/userprog/exec-read
FAIL tests/vm/pt-write-code2
FAIL tests/vm/pt-grow-stk-sc
FAIL tests/vm/page-merge-seq
FAIL tests/vm/page-merge-par
FAIL tests/vm/page-merge-stk
FAIL tests/vm/page-merge-mm

fork-read 케이스 트러블 슈팅

권호형이 디버깅하는 방법을 보여줬습니다. 아직까지 저에겐 디버깅 실력이 부족한 것 같습니다. 해당 트러블 슈팅은 같이 해결해보았습니다. (사실 권호형이 다함)

테스트 케이스에는 msg를 통해 어디까지 테스트가 통과하는지 살펴보고 코드안에서는(do__fork 등) printf를 통해 어디부분에서 넘어가지 않는지 분석해보았습니다.

그 결과 src_page와 dst_page를 찍어보았는데, src_page가 제대로 찍히지 않았습니다. 페이지 type을 잘 걸러내지 못한 것으로 생각되어 if문의 type을 다음과 같이 수정했습니다.

vm.c

supplemental_page_table_copy 수정

수정 사항은 다음과 같습니다. 해당과 같이 바꾸니 마법같이 잘 작동합니다. 그러나 페이지 테이블 kill하는 supplemental_page_table_kill 함수에 문제가 생겨 고치고 있습니다.

기존의 해당 코드를

if (type == VM_UNINIT)

다음과 같이 수정

if (src_page->operations->type == VM_UNINIT)

페이지 삭제 부분을 수정중인데, 문제가 계속 생깁니다. fork-read가 되는 코드는 destroy가 안된다.

→ 일단 계속해서 supplemental_page_table_kill , page_destroy 부분을 수정하고 있다. 해당 부분이 해결되면 다음 것도 해야되는데, 이러다가 mmap를 언제할지…. 계속 디버깅을 해봐야될 것 같다.
내일은 스택 그로우 이해도 해야한다…

하루의 마지막.

채호형이 사준 노티드 도넛을 먹었다. 정말 맛있었다~

profile
모든걸 기록하며 성장하고 싶은 개발자입니다. 현재 크래프톤 정글 8기를 수료하고 게임회사에서 일을 하고 있습니다.

0개의 댓글