
🧩 리눅스에서 시스템 콜(System Call) 추적하기: strace
실습
리눅스 시스템에서 유저 프로그램이 커널에게 어떤 요청을 하는지
즉, 어떤 시스템 콜(System Call) 을 호출하는지를 추적하는 방법을 알아보겠습니다.
시스템 콜 추적은 단순히 개발 실습 수준을 넘어,
운영체제의 내부 동작을 이해하고, 성능 병목이나 디버깅 포인트를 찾는 데 매우 중요한 기술입니다.
🧠 배경: 리눅스가 왜 필요한가?
먼저 시스템 콜을 이해하기 위해선,
“리눅스가 어떤 역할을 하는지”부터 짚고 넘어가야 합니다.
우리는 노트북, 데스크탑, 서버, 모바일 등 다양한 환경에서
여러 개의 유저 프로그램(예: 카카오톡, 크롬, 게임 등)을 동시에 실행합니다.
이때 이 프로그램들이 실제로 사용해야 하는 하드웨어 자원은 다음과 같습니다.
-
🧮 CPU
-
🧠 Memory
-
💾 Disk
-
🌐 Network
이 네 가지가 컴퓨터의 핵심 자원입니다.
문제는,
각 프로그램이 이 자원들을 직접 제어하기에는 너무 복잡하다는 점입니다.
예를 들어 네트워크만 해도,
-
유선/무선 칩 종류 다양
-
제조사 및 버전 차이
-
드라이버마다 인터페이스 상이
결국 개발자 입장에서는 “카카오톡”을 개발하면서
전 세계의 모든 네트워크 카드나 디스크 종류를 일일이 고려해야 하는 불가능한 상황이 됩니다.
이 복잡함을 해결하기 위해 운영체제(OS) 가 등장했습니다.
바로 리눅스(Linux) 가 그 역할을 담당합니다.
✅ 리눅스의 핵심 역할:
유저 프로그램과 하드웨어 사이를 중개
자원 충돌을 방지하고, 공정하게 분배
CPU, 메모리, 디스크, 네트워크 등의 자원 관리
즉, 리눅스는 하드웨어 관리자이자, 프로그램 관리자입니다.
🧩 시스템 콜(System Call)이란?
이제 본론으로 들어가서,
“시스템 콜”은 유저 프로그램이 리눅스에게 요청을 보내는 공식적인 통로입니다.
유저 프로그램은 하드웨어를 직접 제어하지 못하고,
반드시 리눅스를 거쳐야 합니다.
예를 들어:
동작 | 호출되는 시스템 콜 | 설명 |
---|---|---|
파일 열기 | open() |
디스크 파일 핸들 확보 |
파일 읽기 | read() |
파일 또는 네트워크 버퍼 읽기 |
파일 쓰기 | write() |
데이터 기록 |
네트워크 연결 | socket() |
네트워크 자원 오픈 |
데이터 전송 | send() / recv() |
네트워크 통신 |
즉,
📌 시스템 콜 = 유저 프로그램이 커널에게 보내는 요청(명령문)
리눅스 커널에는 300~400개 정도의 시스템 콜이 존재하며,
이 중 open
, read
, write
는 거의 모든 프로그램이 사용하는 가장 대표적인 콜입니다.
🔍 시스템 콜 추적이란?
“시스템 콜 추적”이란 말 그대로
프로그램이 실행되는 동안 어떤 시스템 콜을 호출했는지 기록하고 분석하는 작업입니다.
이 과정을 통해 우리는 다음과 같은 정보를 얻을 수 있습니다:
-
어떤 자원을 사용했는지 (디스크, 네트워크 등)
-
어떤 순서로 호출이 일어났는지
-
어떤 시스템 콜이 오래 걸리는지 (병목 지점)
-
호출 빈도와 인자값(Arguments)
이를 가능하게 해주는 도구가 바로 strace
입니다.
⚙️ strace
명령어 소개
strace
는 리눅스의 강력한 시스템 콜 추적 도구입니다.
어떤 유저 프로그램이 내부적으로 커널과 어떤 식으로 상호작용하는지 한눈에 볼 수 있습니다.
기본 사용법
print('hello world!')
예를 들어, 단순히 폴더 목록을 보여주는 ls
명령어를 추적해보겠습니다.
strace ls
이 명령어를 실행하면,
ls
가 실행되는 동안 발생하는 모든 시스템 콜이 터미널에 출력됩니다.
예시 출력:
openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 getdents64(3, 0x55e9a50f4c00, 32768) = 96 write(1, "Q1.mp4\n", 7) = 7 close(3) = 0
이 결과를 보면,
ls
가 실제로 디렉터리를 열고(openat
), 엔트리를 읽고(getdents64
),
**결과를 화면에 출력(write
)**하는 과정을 확인할 수 있습니다.
🧮 통계 모드 사용하기
시스템 콜의 실행 횟수와 시간 통계를 보려면 -c
옵션을 사용합니다.
strace -c ls
출력 예시:
% time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 50.00 0.000010 5 2 openat 30.00 0.000006 6 1 getdents64 20.00 0.000004 4 1 write
이렇게 하면 각 시스템 콜이 몇 번 실행되었는지, 얼마나 시간이 걸렸는지를 한눈에 볼 수 있습니다.
📁 로그 파일로 저장하기
strace
결과를 로그 파일로 저장할 수도 있습니다.
strace -o trace.log ls
이제 trace.log
파일 안에는 ls
가 호출한 모든 시스템 콜이 기록되어 있습니다.
원하는 만큼 자세히 분석할 수 있죠.
예를 들어 상위 50줄만 확인하려면:
head -n 50 trace.log
🔧 자주 사용하는 옵션 요약
옵션 | 설명 |
---|---|
-c |
시스템 콜별 통계 출력 |
-o <파일> |
결과를 파일로 저장 |
-tt |
호출 시각을 마이크로초 단위로 표시 |
-T |
각 시스템 콜의 수행 시간을 표시 |
-f |
자식 프로세스까지 추적 |
-e trace=<콜명> |
특정 시스템 콜만 추적 (예: -e trace=open,read,write ) |
strace -tt -T -f -e trace=read,write curl https://example.com
🧪 실습: Level-Up Challenge
리얼리눅스
사이트에서는 레벨업챌린지 Q8. 실습
https://reallinux.co.kr/level-up/p/1/p/1/8/
“8번 실습: 시스템 콜 추적하기” 문제를 통해
실제 환경에서 strace
를 사용해볼 수 있습니다.
💡 직접 작성한 프로그램을
strace
로 감싸서 실행하면,
그 프로그램이 어떤 시스템 콜을 호출하는지 전부 확인할 수 있습니다.
🧠 마무리
시스템 콜은 리눅스의 심장부입니다.
모든 유저 프로그램이 결국 이 시스템 콜을 통해서만 하드웨어 자원에 접근합니다.
strace
는 이런 호출 과정을 가시화하는 최고의 도구이며,
이를 이해하면 단순한 명령 실행이 아니라,
운영체제의 내부 구조와 동작 원리를 실제로 “보는” 단계로 나아갈 수 있습니다.
🎯 정리하자면
시스템 콜은 유저 프로그램과 커널 간의 요청 인터페이스
strace
는 시스템 콜을 추적하는 도구통계, 로그, 특정 콜 필터링 등 다양한 옵션을 활용 가능
이제 여러분도 단순히 명령어를 실행하는 수준을 넘어서,
그 명령이 커널 내부에서 어떤 일들을 수행하는지 추적할 수 있게 되었습니다.
추가적으로 리눅스 커널과 시스템콜을 더 공부하고싶다면 리눅스 커널 중급 A를 참고하세요. https://reallinux.co.kr/course/linux_kernel_a