Linux에서 실행되는 모든 프로그램은 파일을 읽고, 네트워크에 접속하고, 메모리를 할당하며, 새로운 프로세스를 생성합니다. 하지만 응용 프로그램은 CPU, 메모리, 디스크 같은 하드웨어를 직접 제어할 수 없습니다.
이때 사용자 프로그램(User Space)과 커널(Kernel Space)을 연결하는 역할을 하는 것이 바로 System Call(시스템 콜) 입니다.
System Call은 Linux 운영체제의 핵심 인터페이스이며, 모든 응용 프로그램은 System Call을 통해 커널의 기능을 사용합니다. 이번 글에서는 System Call의 개념과 동작 원리, 주요 종류, 그리고 실무에서 확인하는 방법까지 자세히 알아보겠습니다.
System Call이란?
System Call은 사용자 프로그램이 Linux Kernel에 서비스를 요청하는 공식적인 방법입니다.
응용 프로그램은 직접 하드웨어를 제어하지 않고, Kernel에 필요한 작업을 요청합니다.
예를 들어
- 파일 열기
- 파일 읽기
- 파일 쓰기
- 프로세스 생성
- 네트워크 연결
- 메모리 할당
이 모든 작업은 System Call을 통해 수행됩니다.
System Call의 동작 구조
System Call의 흐름은 다음과 같습니다.
User Program
↓
System Call
↓
Kernel Space
↓
Hardware
↓
Kernel
↓
User Program
사용자가 실행한 프로그램은 System Call을 호출하고, Kernel은 해당 요청을 처리한 뒤 결과를 다시 사용자 프로그램으로 전달합니다.
왜 System Call이 필요한가?
만약 응용 프로그램이 직접 하드웨어를 제어할 수 있다면 다음과 같은 문제가 발생할 수 있습니다.
- 다른 프로세스 메모리 접근
- 파일 시스템 손상
- 디스크 오류
- 운영체제 충돌
- 보안 취약점
System Call은 이러한 문제를 방지하기 위해 Kernel이 모든 하드웨어 접근을 관리하도록 만든 인터페이스입니다.
대표적인 System Call 종류
Linux에는 수백 개의 System Call이 존재하지만 실무에서 자주 사용하는 것은 다음과 같습니다.
파일 관련
- open()
- read()
- write()
- close()
- lseek()
프로세스 관련
- fork()
- execve()
- wait()
- exit()
메모리 관련
- mmap()
- brk()
- munmap()
네트워크 관련
- socket()
- bind()
- listen()
- accept()
- connect()
- send()
- recv()
기타
- getpid()
- getuid()
- kill()
- uname()
파일을 읽을 때 발생하는 System Call
예를 들어 다음 명령을 실행합니다.
cat test.txt
실제로는 다음과 같은 과정이 발생합니다.
cat 실행
↓
open()
↓
read()
↓
write()
↓
close()
사용자는 단순히 파일을 출력했다고 생각하지만, 내부에서는 여러 개의 System Call이 연속적으로 실행됩니다.
웹 서버도 System Call을 사용한다
Nginx나 Apache도 예외가 아닙니다.
클라이언트 요청이 들어오면
accept()
↓
read()
↓
open()
↓
read()
↓
write()
↓
close()
수많은 System Call을 반복 수행하면서 서비스를 제공합니다.
System Call 확인하기
가장 많이 사용하는 도구는 strace입니다.
프로그램에서 발생하는 모든 System Call을 확인할 수 있습니다.
예시
strace ls
출력 예시
openat()
read()
write()
close()
exit_group()
프로그램이 어떤 System Call을 사용하는지 확인할 수 있습니다.
특정 프로세스 추적하기
실행 중인 프로세스를 추적할 수도 있습니다.
strace -p PID
예를 들어
strace -p 1234
현재 실행 중인 프로세스의 System Call을 실시간으로 확인할 수 있습니다.
특정 System Call만 보기
파일 관련만 확인
strace -e trace=file ls
네트워크 관련만 확인
strace -e trace=network curl google.com
프로세스 관련만 확인
strace -e trace=process bash
필요한 System Call만 선택적으로 분석할 수 있습니다.
System Call과 Library Function의 차이
많은 사람이 C 라이브러리 함수와 System Call을 혼동합니다.
예를 들어
printf("Hello");
는 Library Function입니다.
반면
write()
는 System Call입니다.
일반적으로 Library Function이 내부적으로 System Call을 호출하는 구조입니다.
System Call과 Context Switch
System Call이 호출되면 CPU는 User Mode에서 Kernel Mode로 전환됩니다.
이 과정을 Mode Switch라고 합니다.
주의할 점은 이것은 Context Switch와는 다른 개념입니다.
- Mode Switch : User Space ↔ Kernel Space 전환
- Context Switch : 실행 중인 프로세스 변경
두 개념은 실무에서도 자주 혼동되므로 구분해서 이해해야 합니다.
실무에서 자주 사용하는 명령어
Kernel 버전 확인
uname -r
System Call 추적
strace ls
실행 중인 프로세스 추적
strace -p PID
Kernel 로그 확인
dmesg
System Call 개수 확인
ausyscall --dump
(일부 배포판에서는 audit 패키지가 설치되어 있어야 합니다.)
자주 묻는 질문
System Call은 누가 호출하나요?
응용 프로그램이 필요한 작업을 수행할 때 자동으로 호출합니다. 개발자가 직접 호출할 수도 있고, 라이브러리를 통해 간접적으로 호출될 수도 있습니다.
System Call은 느린가요?
User Space와 Kernel Space를 오가기 때문에 일반 함수 호출보다 비용이 큽니다. 따라서 고성능 애플리케이션은 불필요한 System Call을 줄이는 방향으로 설계합니다.
strace는 운영 중인 서버에서도 사용할 수 있나요?
가능하지만 모든 System Call을 추적하면 성능에 영향을 줄 수 있습니다. 운영 환경에서는 필요한 프로세스나 특정 System Call만 선택적으로 추적하는 것이 좋습니다.
마무리
System Call은 사용자 프로그램과 Linux Kernel을 연결하는 핵심 인터페이스입니다. 파일 입출력, 네트워크 통신, 메모리 관리, 프로세스 생성 등 거의 모든 시스템 작업은 System Call을 통해 이루어집니다. strace와 같은 도구를 활용하면 프로그램이 실제로 어떤 System Call을 사용하는지 확인할 수 있으며, 이는 성능 분석과 장애 분석에서도 매우 중요한 기술입니다.