- 개인적으로 공부하면서 지속적으로 정보를 추가, 수정, 삭제합니다.
- 정확하지 않은 부분 피드백 주시면 감사합니다.
- 노란색 하이라이트는 블로그 주인의 생각 + 개인적으로 이해가 더 필요한 부분을 표시한 것입니다. 특별히 더 중요한 개념으로 표시한 것이 아닙니다.
- TIL/WIL 노트의 일부를 정리해서 적합한 카테고리의 노트 항목에 추가합니다.
2022-12-26, 2022-12-27
C언어 - strtok_r() 함수 사용
왜?
argument passing 구현에서 명령행 인자 parsing을 위해 사용한 함수.
어떻게?
☞ C언어 문법 & 개념 정리 노트에 추가
C언어 - memset 함수 사용법
참고: [C언어/C++] memset 함수 메모리 초기화 (tistory.com)
☞ C언어 문법 & 개념 정리 노트에 추가
왜?
argument passing 구현에서 명령행 인자 parsing을 위해 사용한 함수.
어떻게?
#include <memory.h> 혹은 <string.h>
void* memset(void* ptr, int value, size_t num);
매개변수
ptr: 세팅하고자 하는 메모리의 시작 주소
value: 메모리에 세팅하고자 하는 값
num: 길이. ptr에서 value까지의 바이트 길이.
반환 값
성공하면 첫번째 인자로 들어간 ptr을 반환
실패한다면 NULL을 반환
2022-12-27, 2022-12-28
Pintos Project 2 System Call 카이스트 강의
참고: https://www.youtube.com/watch?v=sBFJwVeAwEk
왜?
시스템 콜이란?
시스템 콜을 pintos에서 어떻게 구현할 것인가
무엇?
시스템 콜
- OS에 의해 제공되는 서비스를 위한 프로그램밍 인터페이스
- 유저 모드의 프로그램들이 커널을 이용할 수 있게 해줌
- 커널 모드에서 동작(
int n
명령 )하며, 유저 모드로 리턴함 - 중요한 것은; 유저 모드에서 커널 모드로 넘어갈 때 우선 순위가 스페셜 모드로 올라감 → 시스템 콜을 부르기 위해 하드웨어 인터럽트가 생성되었기 때문
★ 현재 핀토스 문제! syscall handler의 body가 비어있다! → syscall handler의 body를 채우자. 그러기 위해서는 system call을 구현해야 한다!
프로세스 계층 process hierarchy
- 부모 프로세스가 누군지, 자식 프로세스가 누군지 특정지어야 한다
- siblings를 가리키는 포인터를 가지고 있어야 한다
PintOS Project1 try-error 추가
참고:
무엇?
PintOS Project 1의 void test_max_priority(void)
함수가 제대로 동작하지 않는 에러 해결
왜?
PintOS Project 2하다가 스레드 부분에서 에러 나는 걸 발견해서
어떻게?
- 되는 코드의 슈도코드
- 슬립 리스트가 비어있지 않고,
- 현재의 스레드의 우선순위 < 슬립 리스트의 첫번째 원소의 우선순위
- 인터럽트 처리중이 아닐 때 (
!intr_context()
) - 위의 조건을 모두 만족할 때
thread_yield()
- 수정 & 확인 사항
- cur 을 thread_current로 바로 받음 (중간에 현재 쓰레드 바뀔까봐 -> 상관 없었다)★
- 리스트 엠티 확인
- 레디리스트의 첫째를 변수로 저장 안하고 바로 받음 (중간에 레디 리스트 첫째가 바뀔까봐 -> 상관 없었다)★
- cmp_priority 함수 사용 안함 (함수로 넘겨주면서 바뀌거나, 등호 때문으로 추측)★★★ 이놈이 원인
- begin -> front로 바꿔 써봄 (차이 없었다)
- 내 코드와의 차이점
결론부터 말하면,cmp_priority
함수를 사용하지 않고 직접 priority를 비교하는 코드로 수정하여 해결.
우선순위를 비교함수 안에는=
가 true에 포함되지 않음 → 러닝 스레드가 우선순위가 같은 경우에서 차이가 있었음.
// 수정한 코드
// P1 Priority: 러닝 스레드와 레디 리스트 첫 스레드의 우선순위와 비교 → 스케줄링
void test_max_priority(void)
{
struct thread *cur = thread_current();
struct list_elem *ready_begin = list_begin(&ready_list);
if (list_empty(&ready_list))
return;
if (cur->priority >= list_entry(ready_begin, struct thread, elem)->priority)
return;
if (intr_context()) // P2 에러 방지를 위해 추가
return;
thread_yield();
}
// 기존 코드
void test_max_priority(void)
{
struct list_elem *begin = list_begin(&ready_list);
if (list_empty(&ready_list))
return;
bool cmp_val = cmp_priority(&thread_current()->elem, begin, NULL);
if (cmp_val == true)
return;
if (!intr_context())
thread_yield();
}
Syscall from gitbook
참고:
시스템 콜 from gitbook
- 시스템 콜 핸들러
- 시스템 콜 넘버 받기
- 시스템 콜 인수 받기
- 적절한 액션 수행하기
- 시스템 콜 디테일
- OS는 외부 인터럽트로 유저로부터 컨트롤을 되찾을 수 있다; timer와 I/O 기기로부터의 인터럽트
- 외부 인터럽트란 CPU 밖의 주체로부터 야기된 인터럽트임
- OS는 또한 소프트웨어 예외를 다룸; 프로그램 코드에서 발생하는 이벤트 e.g.; 페이지 폴트, 디비전 바이 제로
- 예외는 유저 프로그램이 OS에게 서비스(“system call”)를 요청하는 수단이다
- x86-64 아키텍쳐에서, 시스템 콜 핸들러를 호출하는 특별한 명령
syscall
을 도입함 (기존에는 다른 소프트웨어 예외와 동일하게 다뤄짐)
syscall
명령syscall
은 시스템 콜을 호출하기 위해 현대에서 가장 흔히 사용되는 수단 (핀토스에서도 마찬가지)syscall
명령을 호출하기 전, 시스템 콜 넘버, 추가적인 시스템 콜 인수들은 다음 레지스터들에 저장되어야 한다;%rax
는 시스템 콜 넘버- 네 가지 인수는
%r10
(%rcx
❌) %rdi
,%rsi
,%rdx
,%r10
,%r8
, and%r9
try-error “Page fault at 0xa: not present error reading page in kernel context.”
참고:
무엇?
접근되는 메모리의 페이지가 현재 물리 메모리에서 사용가능하지 않다. 예를 들어 페이지를 이제 현재 사용하지 않아서 이미 하드 드라이브같은 2차 저장기기로 스왑 아웃 되었거나, 그 페이지가 프로세스에게 아직 할당되지 않았거나.
OS가 커널 모드에서 실행 중일 때(in kernel context), 메모리 페이지에 엑세스하려고 시도하는 동안 오류가 발생했음을 나타냄.
어떻게?
read
와 write
함수에서 STDIN
, STDOUT
의 경우 예외 처리 해주기
try-error exit(status)
테스트 케이스 통과 시 조심 할 점
참고:
무엇?
exit(-888)
처럼 나만 알아볼 수 있는 숫자를 이용하여 디버깅할 수 있음
but 테스트 케이스를 통과하려면 exit(-1)
로 다시 고쳐놓아야 PASS 뜨므로 조심할 것.
close-twice 에러 메시지
참고:
무엇?
close-twice 에러 메시지
cur->fdt[fd] = 0
으로 엔트리 초기화를 할 때, f = 0
처럼 무심코 변수를 사용했다가 현기증나는 커널 패닉 🥹
이건 정말 주의해야 하는 실수다.
file을 0으로 만드는 것이 아니라, fdt의 엔트리를 0으로 만드는 것이기 때문에!
FAIL tests/userprog/close-twice
Kernel panic in run: PANIC at ../../filesys/inode.c:327 in inode_allow_write(): assertion `inode->deny_write_cnt > 0' failed.
Call stack: 0x8004217eb4 0x800421fb29 0x800421e980 0x800421e72d 0x800421d345 0x800421cc1a 0x800421c8ff 0x40019d 0x4001fb 0x400c9c
Translation of call stack:
0x0000008004217eb4: debug_panic (lib/kernel/debug.c:32)
0x000000800421fb29: inode_allow_write (filesys/inode.c:328)
0x000000800421e980: file_allow_write (filesys/file.c:144)
0x000000800421e72d: file_close (filesys/file.c:60)
0x000000800421d345: close (userprog/syscall.c:343)
0x000000800421cc1a: syscall_handler (userprog/syscall.c:109)
0x000000800421c8ff: no_sti (userprog/syscall-entry.o:?)
0x000000000040019d: (unknown)
0x00000000004001fb: (unknown)
0x0000000000400c9c: (unknown)
load 세마포어를 추가한 후 발생하는 에러
참고:
무엇?
load 세마포어를 추가한 후 발생하는 에러 // null인 elem이 리스트에 추가된 것 같다?!
아무래도 부모, 차일드 포인터 지정이 잘못 된 듯.
FAIL tests/userprog/args-none
Kernel panic in run: PANIC at ../../lib/kernel/list.c:362 in find_end_of_run(): assertion `a != NULL' failed.
Call stack: 0x8004217eb4 0x8004218b1d 0x8004218fd5 0x800420a146 0x800421b7fd 0x800421b554 0x800420744a
Translation of call stack:
0x0000008004217eb4: debug_panic (lib/kernel/debug.c:32)
0x0000008004218b1d: find_end_of_run (lib/kernel/list.c:363)
0x0000008004218fd5: list_sort (lib/kernel/list.c:427)
0x000000800420a146: sema_up (threads/synch.c:125)
0x000000800421b7fd: process_exec (userprog/process.c:220)
0x000000800421b554: initd (userprog/process.c:95)
0x000000800420744a: kernel_thread (threads/thread.c:449)
exec() 구현할 때 process_create_initd
를 사용하면 어려운 이유
참고:
왜?
카이스트 핀토스 강의 & pdf에서 process_create_initd()
를 사용하라고 언급하는데 아마 업데이트가 안된 듯 하다. 해당 함수를 사용하면 불편하다.
어떻게?
exec()을 구현할 때 process_exec() 함수를 이용하는 것이 편하다.
처음에는 process_create_initd 를 이용하여 구현했다가 바꾸었다.
이유는, exec-misssing 같은 테케를 통과하기 위해서 return -1을 받아야 하는 경우가 있는데,
process_create_initd -> initd -> process_exec로 이어질 때,
process_exec에서 return -1을 하면 initd가 바로 exit(-1) or 커널 패닉을 반환하면서 스레드가 종료되기 때문에,
exec() 함수가 아무것도 반환하지 못한다.
따라서 process_exec
을 사용하는 것이 편하다.
'크래프톤정글 > PintOS' 카테고리의 다른 글
크래프톤정글 PintOS; Project 3 Diagram (Anonymous Page 까지) (0) | 2023.01.21 |
---|---|
크래프톤정글 PintOS; Project 1, 2 Diagram (0) | 2023.01.21 |
크래프톤정글 9-10주차; WIL - PintOS Project 3 Virtual Memory (0) | 2023.01.21 |
크래프톤정글 8주차; WIL - PintOS Project 1 Threads (0) | 2022.12.22 |