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)로
뜨진 않는데...그냥 제가 망한거같아욤
없음...
내일은 랜덤 런취
추웁다...
총 정리 하기.
총 정리 으쌰으쌰하기.
총 정리!! 하고
발표 준비하기
카페 음료 먹기엔 ...
그치만 에이드는 좀 땡기는군