[Week11] 0402

안나경·2024년 4월 2일

크프정 일상

목록 보기
82/109

어제의 이야기

어제 공부한 것

  • 다른 사람 코드를 모두 넣고 evict, anon 파트를 그대로 복붙해도 같은 에러가 뜬다.
  • mmap bad off 케이스는 offset > length 일시 NULL 처리 해주면 해결.
  • mmap inherit 추적 중, VM_FILE 타입이 do claim page 까지 잘 끝내고도 exit(-1)로 죽는 것을 확인. 어느 지점에서 죽는지 알수가 없다...
  • intr_context 가 아니라는, 내가 겪는 swap 케이스가 printf시 나오는 문구와 같아서 printf 관련인가 주석처리하다가 깨달았는데, 3천개 시점에서는 Thread is not... 즉, thread 가 아니라는 문구가 나와서 관련이 없다는 생각이 듦. (근데 3천개 이전 시점에는 intr_context가 아니라는 에러가 뜨니까 어디선가 인터럽트 관련 에러인거 같긴 함.)
  • 3천개 시점이 팀원분 코드에서 확인하니 맨처음 frame 출력 시점이라 생각했지만(아마도? 아닐수도. 그 때 나오는 주소가 4만대인데, 사실 frame은 전부 힙 영역에 적재되므로 4만대 주소가 나오지 않는다.) frame table 길이는 고작해야 1215개밖에 되지 않아서 맨처음으로 돌아온게 그 시점이라는게 말도 안됨.
  • write-bad2 는 코드 segment 에 쓰면 안되는 케이스로, page가 writable이 아닐시 exit(-1)로 종료하면 해결. (물론 writable은 별도의 변수를 thread에 추가해서 갱신해주고 있었어야함.)

swap이 안 되는 케이스에 관해 내 질문과
조교님에 대한 답변.

swap anon 구현 중, 랜덤한 시점에서 Kernel PANIC at ../../threads/thread.c:342 in thread_current(): assertion `is_thread (t)' failed.가 일어납니다.
되는 팀원의 코드를 모두 대체하여도 항상 같은 에러가 나는 것을 확인하여(여러 코드, 무슨 코드든 이런 에러가 일어남.(즉, anon.c의 swap out, in, 그리고 vm.c의 get frame중 kva가 palloc이 안될경우 타는 함수 전반을 대체하였을 경우.)) 어디서부터 봐야할지 감이 잡히지 않습니다.
단순히 (swap-anon) write sparsely over page 2560등 swap in 시점에서 나는 경우도, (swap-anon) check consistency in page 3072등 swap out과 swap in이 일어나는 시점에서도 일어납니다.
딱 3072 지점 이후부터 기존 swap disk 용량에서 사용했더라면 첫번째 frame으로 (주소상... frame을 일일이 free 시키지않고 kva만 지워서 재활용했다면.) 넘어가는 시점에서 에러가 나 그걸 못찾는 줄 알았는데, 랜덤하게 일어나기도 하니 그건 아닌듯 하고.. make clean을 혹시 몰라 진행해도 똑같습니다.
혹시 어느 부분에서 문제가 될만한지(process든, thread든, ...) 감이라도 잡고 싶어 여쭤봅니다.
(랜덤하게 일어나기떄문에 fault addr 주소는 늘 일정하게 나오진 않음.)

cr2=0000000000000018 error=               0
rax 0000800421ae9500 rbx 0000800423ef1800 rcx 00000080040b8000 rdx 00000000000003d4
rsp 000000800423d440 rbp 000000800423d450 rsi 000000000000880f rdi 0000000000000000
rip 00000080042158d4 r8 000000800423d358  r9 000000800421bd13 r10 0000000000000000
r11 0000000000000202 r12 0000800423df1000 r13 0000800420afce00 r14 0000800423df1000
r15 00000000000000ff rflags 00000006
es: 0010 ds: 0010 cs: 0008 ss: 0010
Kernel PANIC recursion at ../../userprog/exception.c:97 in kill().
Interrupt 0x0d (#GP General Protection Exception) at rip=8004220d9c
 cr2=0000000000000018 error=               0
rax cccccccccccccccc rbx 0000000000000000 rcx 0000008004223996 rdx 0000000000000007
rsp 000000800423ceb0 rbp 000000800423cec0 rsi 0000000000000156 rdi cccccccccccccccc
rip 0000008004220d9c r8 0000008004223a2f  r9 00000080042187bf r10 0000000000000000
r11 0000000000000202 r12 0000800423df1000 r13 0000800420afce00 r14 0000800423df1000
r15 00000000000000ff rflags 00000002
es: 0010 ds: 0010 cs: 0008 ss: 0010
Interrupt 0x0d (#GP General Protection Exception) at rip=8004220882
 cr2=0000000000000018 error=               0
rax cccccccccccccccc rbx 0000000000000000 rcx 0000008004228248 rdx 0000000000000010
rsp 000000800423cca0 rbp 000000800423ccb0 rsi 000000000000000a rdi cccccccccccccccc
rip 0000008004220882 r8 00000080042187bf  r9 000000800421bd13 r10 0000000000000000
r11 0000000000000202 r12 0000800423df1000 r13 0000800420afce00 r14 0000800423df1000
r15 00000000000000ff rflags 00000086
es: 0010 ds: 0010 cs: 0008 ss: 0010
....
Kernel panic in run: PANIC at ../../threads/thread.c:342 in thread_current(): assertion `is_thread (t)' failed.
...
0x000000800421889a: debug_panic (lib/kernel/debug.c:32)
0x000000800420714b: thread_current (threads/thread.c:343)
0x000000800420afa8: lock_release (threads/synch.c:269)
0x000000800420c597: malloc (threads/malloc.c:125)
0x0000008004221a39: spt_find_page (vm/vm.c:120)
0x0000008004221ff6: vm_try_handle_fault (vm/vm.c:443)
...
x0000008004209751: intr_handler (threads/interrupt.c:352)
0x0000008004209b6f: intr_entry (threads/intr-stubs.o:?)
0x0000008004221ff6: vm_try_handle_fault (vm/vm.c:443)
0x000000800421d6f7: page_fault (userprog/exception.c:152)
0x0000008004209751: intr_handler (threads/interrupt.c:352)
0x0000008004209b6f: intr_entry (threads/intr-stubs.o:?)
0x0000000000400cac: (unknown)
0x0000000000400cf5: (unknown)

조교님 답변.

보내주신 설명과 오류 메시지만으로는 정확히 어떤 상황에서 오류가 발생한 것인지 알기 어렵습니다. 다만 의심이 가는 부분 두 가지를 알려 드립니다.

"랜덤한 시점"에서 오류가 일어나는 것으로 봤을 때, 동시성 오류의 가능성이 높아 보입니다. 즉 코딩할 때는 A -> B의 흐름이 당연하다고 생각하고 코딩했는데, lock이나 semaphore가 적절히 활용되지 않아 A와 B의 순서가 바뀌는 경우가 발생하는 것입니다. 코드의 흐름이 어디서든지 timer interrupt에 의해 다른 thread로 넘어갈 수 있다는 사실을 기억하고 lock을 통해 원하는 처리의 흐름이 보장되는지 확인해 보세요.

"is_thread(t) failed"라는 메시지는 kernel stack이 가득 차서 page의 처음 부분에 있는 thread 구조체의 magic number를 손상시켰을 때 발생합니다. 또한 메시지에서 나온 "Kernel PANIC recursion"이라는 메시지를 보았을 때, 작성하신 fault handler에서 결과적으로 다시 fault가 발생하는 무한 루프가 일어나고 있는 것으로 생각됩니다. page fault handler에서 이미 swap out된 page를 다시 swap out하려고 하거나, swap in된 page인 것처럼 다루는 등 다시 page fault가 일어날 만한 행동을 하고 있지는 않은지 확인해 보세요.

좀 더 일반적인 버그 해결 방법으로, 이러한 버그가 일어나지 않은 과거 시점과 버그가 일어나고 있는 현 시점의 코드 사이를 이분 탐색(bisect)하여 어떤 코드가 도입되었을 때 버그가 만들어졌는지 확인하는 방법이 있습니다. swap-anon을 구현하기 전과 현재 코드의 차이가 무엇인지 검토해 보세요. 다만 기존에 있던 버그가 숨어 있다가 나중에 드러난 경우일 수도 있기 때문에 주의가 필요합니다.

[9:17 PM] 특히 일부 레지스터 값이 cccccccccccccccc 인 것으로 봐서, 이미 swap-out되거나 free된 page를 접근하는 것으로 의심됩니다. 이 부분을 집중적으로 검토해보세요.
https://casys-kaist.github.io/pintos-kaist/appendix/debugging_tools.html 의 맨 밑, Tips를 참고하세요.

소감

조교님....
사랑합니다...
에러 자체가 무슨 원인이 추정되는지 알게 되어
무척 기쁜 시간.....

근데 Tip을 보니 저의 에러가
Interrupt 0x03 (#BP Breakpoint Exception)로
뜨진 않는데...그냥 제가 망한거같아욤

오늘의 계획

변경 사항 및 일정

없음...
내일은 랜덤 런취

오전

추웁다...
총 정리 하기.

총 정리 으쌰으쌰하기.

저녁

총 정리!! 하고
발표 준비하기

오늘의 다짐

카페 음료 먹기엔 ...
그치만 에이드는 좀 땡기는군

profile
개발자 희망...

0개의 댓글