
이번주 내내 CSAPP : 7,8,9 장을 읽고 CSAPP:8장을 읽고 예외적인 제외흐름에 대해서 정리했지만, 직접 사용해보지 않았기에 이해하기 어려운 부분이 있었어요.
그런데 저희는 CSAPP만 읽은 게 아니라 RB-tree도 만들었잖아요?
그래서 RB-tree 를 만들 때 사용했던 system call 에 대해서 정리하면 나에게도 도움이 되고 같이 공부하는 여러분들에게도 8장의 내용을 이해하는데에 조금 더 도움이 되지 않을까 해서
이번주 발표 내용은 우리가 사용했던 system call 입니다.
🎯 1. 키워드 공부
🎯 2. 테스트 케이스
🎯 3. 책 읽기
진행률 : 95%
트랩 이란?
시스템 콜은 이 트랩을 발생시켜서 커널에게 요청하는 서비스입니다.
CPU에는 사용자 모드와 커널 모드가 있는데요.
사용자 모드에서는
등을 할 수가 없어요. 그래서 system call이라는 명령어를 이용해서 커널모드로 진입하는 거예요.
| 시스템 콜 | 번호 | 설명 |
|---|---|---|
read | 0 | 파일에서 읽기 |
write | 1 | 파일에 쓰기 |
open | 2 | 파일 열기 |
close | 3 | 파일 닫기 |
fork | 57 | 자식 프로세스 생성 |
execve | 59 | 새 프로그램 실행 |
exit | 60 | 프로세스 종료 |
kill | 62 | 시그널 보내기 |
다양한 system call명령어가 있는데 운영체제마다 다르고
리눅스는 /usr/include/x86_64-linux-gnu/asm/unistd_64.h 경로에 저장되어 있다고 합니다.
우리는 총 5개의 system call을 이번 RB-tree에서 사용했어요.
malloc,freeprintfrand,srand근데 이 중 rand와srand는 test case를 위해서 사용된거고 잘 모르니까 안할게요.
3개만 살펴볼게요. malloc,free,printf
실제로 printf 는 데이터를 그냥 바로 출력하지 않아요.
그 대신 포맷처리와 버퍼링을 담당하고 최종 출력은 write() 시스템 콜 을 사용해서 출력합니다.
왜냐고요? 순수 c 언어로는 터미널에 출력 ( 디스크에쓸수도있음 ) 을 못함 권한이 없어서,
그래서 커널한테 자격 넘겨줄려고 write 써요.
이런 순서를 거쳐요
사용자 코드
└─▶ printf() // 라이브러리 함수
└─▶ vfprintf() // %d , %s , %p 포맷 처리
└─▶ _IO_file_xsputn() // 버퍼(버퍼는 데이터를 임시로 저장해두는 공간) 에 데이터 복사
└─▶ _IO_do_write() // 파일 스트림 flush
└─▶ syscall write(fd=1, buf, size)
이렇게 여러 중간과정을 거치고 최종적으로는 write() 시스템 콜을 사용합니다!
write(1, "Hello\n", 6);
유저모드 write() 호출
↓
CPU의 트랩 → 커널 진입 (syscall)
↓
fd 검증 → 버퍼 접근 시도 → 파일디스크립터가 가리키는 대상(터미널,디스크파일)에 기록
↓
오류 발생 시 → 예외(페이지 폴트, 권한 오류 등) → errno 설정 → -1 리턴
malloc 은 내부에 ptmalloc 이라는 힙 관리자가 따로 있는데 얘가 시스템 콜을 관리해줘요.
언제 쓰냐!!
malloc 이 heap 영역에 메모리를 할당하는 건 아시죠?

만약 heap 영역에 메모리가 꽉 차면 이 힙 영역을 늘려줘야 하잖아요.
그 때, 이제 brk() 라는 시스템 콜을 사용해서 조절되는 거예요.
brk() 라는 시스템 콜 사용 ( malloc 의 데이터가 큰 경우 또는 특수한 경우에 mmap() 시스템 콜 사용 )brk 시스템 콜은 인자로 원하는 힙의 끝 주소를 전달해요.
int brk(void *end_data_segment); // 절대주소
void *sbrk(int increment); // 상대주소
혹은 sbrk로 상대적인 주소를 전달하기도 한답니다?
대부분의 경우 free 는 단순히 사용자가 요청한 메모리 블록을 내부 힙 관리구조(free list)에 반환해서 다음에 malloc이 재활용할 수 있도록 표시함.
이건 완전히 사용자 공간에서 처리되고요 시스템 콜이 발생하진 않아요.
free 쓸때 시스템콜이 발생하는 경우는
위에서 쓴 malloc 에서 데이터가 클 경우 mmap()을 쓴다고 했자나여 이걸 쓴 메모리 블록을 free()할 때 넘 크니까 free list에 안넣고 그냥 munmap() 시스템콜을 호출해서 해제해요
왜냐면 brk는 연속된공간을 확장하는 방식인데
mmap은 아예 새로운 메모리 공간을 만드는 느낌이예요.

이런느낌
brk 는 heap 에 바로 연속적으로 만들어지고
mmap은 아예 새로운 공간을 할당했다가 해제할때 그 공간 자체를 해제
마무리
8장이 너무 어려워서 최대한 주변 예제로 이해하고 싶어서 그 경험을 공유합니다.
화이또
나 왜 인상찌푸리고있어ㅠ