[Week9] 0320

안나경·2024년 3월 20일

크프정 일상

목록 보기
70/109

어제의 이야기

어제 공부한 것

알고리즘? 그게 뭐지?
퀴즈 시간에 알고리즘 관련 문제를 보긴 했지...

어제 문구 보니 천지신명이 도왔나보다

  • exit status 반환용으로 sema 추가. process wait 부분과 process exit 부분에 각각 추가하면 됨.
  • execution 되는 동안 write deny 하기위해 deny 부분 추가. setup stack 이전 deny, process exit 시점 file close. (close만해도 allow write 포함됨.)
  • fork is_kernel_vaddr에 걸리는 이슈 해결.
  • file duplicate시 항상 마지막 칸이 이상한 주소가 담겨져있어서 맨 마지막 인덱스는 복사하지 않는 것으로 페이지 폴트 해결.
  • multi oom 케이스에서 212개가 되어야하는데 180개정도밖에 안되어서 file 전부 close 시키고, child list 안에 있는 child process 전부 wait 시켜서 기다릴때 1 time이 안 되어서 머리싸매다 exit status 관련 sema를 process cleanup 위로 올려서 해결.
  • bad 관련으로는 buffer에 null이 있으면 페이지 폴트가 뜨는데, 그거때문에 page fault handler로 넘어간 시점에 그 이슈 관련이면 그냥 exit(-1) 시켜주는 걸로 해결.

fork ...
에 대한 이슈를 알아내기 위해
va가 실제로 어떻게 구성되는지,
duplicate pte에서 들어오는 인자가
어떻게 나온 건지 이해함.

parent->pml4로
참조참조참조한 값으로
물리 메모리 주소인 pte를 받는데
그거 쭉 타고 들어가면서 받은 offset을 뭉쳐서
va도 만들어냄.

pml4가 4레벨 페이지 맵이니
네 번 타고 들어가야 진짜 주소가 뜨는 거였음.

그럼 pml4나 그 안에 있는 거야
페이지 테이블이니 커널 스택에 있을거라 생각됨.

그렇지만 va -> pml4 -> pa 니까
va나 pa 자체는 유저 모드 쪽에 있어야하는게 맞음.

그런데 va가 커널 주소로 간주됨.
막막해짐.

해결된 다른 분 케이스를 봤지만
내 코드랑 진짜로 토씨하나 다른게 없음

슬랙에 울며겨자먹기로 질문올림
그러고도 막막해서 솔루션 코드 갖다붙이니됨
어?

diff 떠봄
똑같음

어?

뭐지?
내 코드에는 컴퓨터의 피가 안 흐르는건가?
주석 . 다지워봄

당연히 상관없음

printf 지워봄

?
?

??
아무튼 그렇게 fork 가 살아났다...

질문 올리자마자 해결한 사람됨
그렇지만 오늘 조교님 답변이 올라옴

If the parent_page is kernel page, then return immediately라고 되어 있는 이유는 pml4_for_each가 duplicate_pte를 주어진 pml4에 존재하는 모든 va를 인수로 각각 실행하기 때문입니다. kernel 영역의 virtual address는 pintos의 kernel virtual address - physical address 일대일 관계에 따라 어느 프로세스에서나 동일하게 접근할 수 있으므로 memcpy 등으로 복제할 필요가 없습니다. 따라서 duplicate_pte에서 is_kernel_vaddr을 이용해 va를 검사하고, kernel virtual address인 경우 true를 반환하는 접근은 맞습니다.
printf를 넣을 경우 해당 출력이 무한히 실행된다고 하셨는데, 제 생각에는 정말 무한은 아니고 아주 많은 유한한 횟수가 실행되는 것 같습니다. kernel virtual page는 꽤 많아서 (physical page의 개수와 같습니다), 많은 printf가 일어날 수 있습니다. printf는 커널 단계에서는 꽤 무거운 함수이기 때문에 (키보드의 락을 잡고 놓는 과정을 반복해야 합니다) 말씀하신 대로 할 경우 "무한하다"고 생각하실 만큼 오래 걸릴 수 있을 것 같습니다.

...조교님 짱!

아무튼,
그 외에는...
deny 개념이 쪼꼼 신기했고,

file duplicate 마지막 인덱스를 넘기면서
나의 정적 배열을 불신했으나
누군가 정적 배열로 해결한 케이스가 있다길래
나의 구조체를 믿고...... 했음.

bad는 생각보다 관련자료가 없어서
exit()를 하면서 반신반의함..
그리고 자신의 자질을 의심함..

마지막에 남은 두개가
하나가 여러개를 fork 했을때
맨 마지막 주소를 0x3이길래 3만 넘기면
그 뒤가 뻑나는게 문제였으나 맨 마지막 인덱스를 넘기는 것으로 해결.

다른 하나는 multi-oom이었는데 아무튼
다들 리스트 구조체로 해서 palloc_free가 해당되지 않았는데
정적 배열 케이스에 file close 나 child process wait 관련 얘기해줘서 해결.

소감

all pass 해서인가
잘 잤다...

총정리하고 발표준비해야지...짱!

오늘의 계획

변경 사항 및 일정

점심 랜덤 런치.

오전

TIL 적고
팀원과 D님과 S님과 fork 뽀개기함.
fork는 뽀갰는데

exec에서
process_exec 시 strlcpy에서
디버깅 걸림.

특이한건 main은 안걸리는데
child는 걸린다는 것.

나는 cmd_line을 복사해서 넘기는 이유가
const 라 안잘려서인줄 알았는데
const 라도 잘리네

흠... const는 뭐지?
이상하다 보통 const는 상수취급 받아서
변경하려고하면 컴파일 당시에 에러가 떠야하는데
(엥 근데 나는 const라서 copy를 따로 만들었네?)
(나중에 코드 확인해야지)

그리고 임의의 배열을 만들때
palloc으로 만드는 이유는
이미 main에 있는 거라면 모를까
syscall 단계 등 load 전에서 만드는건
페이지가 설정이 안되어있어서
palloc get으로 가져와서 복사해야한다는것과

(duplicate_pte 이거 잘못된거아니냐고했는데
내가 함수왕 헷갈려서 틀린건 좀 쪽팔렸다)

fork 시에
나는 intr_frame을 넘겨받으려고
함수 자체를 인자를 추가로 받도록 수정했는데
사실 process fork에서가 아니라
syscall handler 단계에서
memcpy를 해도 문제없이 컨텍스트를 넘겨받을 수 있다는것
좋았다..

팀원분이
모든 test가 터지기 시작했는데
이상하게 idle thread 자체가
ready list에 안들어갔음
(많은 디버깅의 과정이 있었음)

그치만 fork를 만지는 사람이
왜 갑자기 그게 죽는 말인가?
깔끔하게 보이려고 띄어쓰기 및 엔터가
idle thread를 가져갔단 말인가?

인생은 알수가 없다...

아무튼
지금 2시쯤이니까

발표 뭘 할지 정리하고
다 하고 나면 총 정리

저녁

알고리즘! 하고.
총 정리!
하기.

오늘의 다짐

어깨 쑤셔
허리쑤셔

알고리즘.......
해야지..

profile
개발자 희망...

0개의 댓글