strace

Erdos·2025년 7월 26일

LINUX/UNIX

목록 보기
5/8

25강. 시스템 호출(system call) 직접 관찰하기

사용해 보니 strace는 꽤 흥미로운 명령어다.
문제는, 이 안에서 내가 보고 싶은 정보만 추리는 것인데..
옵션을 한두 번 써보고 자꾸 까먹으니 아쉬워서 하는 기록이다.
그리고 man을 번역해서 보니까 꽤 흥미진진..

그런데.. 시스템 모니터링 도구가 제일 좋을지도....?

strace

사용할 파이썬 코드

import os

print("hello world!")
print("my pid is", os.getpid())

manual

man strace

📜description

strace란?

strace는 리눅스에서 동작하는 시스템 콜 추적 도구로, 프로그램이 운영체제 커널과 상호작용하는 과정을 실시간으로 기록해주는 유틸리티다.
사용자 프로그램이 호출하는 시스템 콜과 수신하는 시그널을 가로채고, 각 호출의 이름, 인자, 반환값을 출력해준다.

1. 기본 동작 방식

strace는 지정된 명령어를 실행하고, 그 명령어가 종료될 때까지 시스템 콜을 추적한다.
출력은 표준 에러(stderr) 또는 -o 옵션으로 지정한 파일로 보낼 수 있다.

strace ls

2. strace가 유용한 이유

소스 코드를 보지 않고도 프로그램의 동작 흐름을 파악할 수 있다.

디버깅, 문제 해결, 성능 분석에 매우 유용하다.

유저-커널 인터페이스 수준의 정보를 보여주기 때문에 버그 격리나 경계 조건 분석에 적합하다.

3. 출력 예제

명령어 cat /dev/null을 실행하면 다음과 같은 출력이 나온다:

open("/dev/null", O_RDONLY) = 3

오류가 발생한 경우에는 errno 정보와 함께 출력된다:

open("/foo/bar", O_RDONLY) = -1 ENOENT (No such file or directory)

4. 시그널 처리 예시

sleep 666 실행 중 Ctrl+C로 인터럽트를 보내면:

sigsuspend([] <unfinished ...>
--- SIGINT {si_signo=SIGINT, si_code=SI_USER, si_pid=...} ---
+++ killed by SIGINT +++

5. 멀티스레드 / 병렬 실행 처리

서로 다른 프로세스/스레드가 시스템 콜을 동시에 호출할 경우 unfinished, resumed 태그로 연결된다

[pid 28772] select(4, [3], NULL, NULL, NULL <unfinished ...>
[pid 28779] clock_gettime(CLOCK_REALTIME, {...}) = 0
[pid 28772] <... select resumed> ) = 1 (in [3])

6. 시그널에 의해 중단된 시스템 콜

read(0, 0x7ffff72cf5cf, 1) = ? ERESTARTSYS (To be restarted)
--- SIGALRM {si_signo=SIGALRM, si_code=SI_KERNEL} ---
rt_sigreturn({mask=[]}) = 0
read(0, "", 1) = 0

7. 다양한 인자 표현 예

open("xyzzy", O_WRONLY|O_APPEND|O_CREAT, 0666) = 3

플래그는 비트 OR 조합으로 표시되고
퍼미션은 전통적으로 8진수로 출력된다

8. 구조체 출력 예

lstat("/dev/null", {st_mode=S_IFCHR|0666, st_rdev=makedev(0x1, 0x3), ...}) = 0

구조체의 각 멤버가 명시적으로 해석된다
st_mode는 비트 OR된 심볼 + 숫자 조합으로 디코딩된다

9. 실패 시 구조체 역참조 생략 예

lstat("/foo/bar", 0xb004) = -1 ENOENT (No such file or directory)

시스템 콜이 실패하면 출력 인자가 역참조되지 않을 수 있다

10. 알 수 없는 시스템 콜 예

syscall_0xbad(0x1, 0x2, 0x3, 0x4, 0x5, 0x6) = -1 ENOSYS (Function not implemented)

strace가 인식하지 못하는 시스템 콜은 번호와 함께 raw 형식으로 출력된다

11. 문자열 및 배열 출력 방식

read(3, "root::0:0:System Administrator:/"..., 1024) = 422
getgroups(32, [100, 0]) = 2

문자열은 32바이트까지만 출력하고 ... 생략 부호를 붙인다
배열은 [] 안에 콤마로 구분하여 출력된다

12. 비트셋 출력 예

sigprocmask(SIG_BLOCK, [CHLD TTOU], []) = 0
sigprocmask(SIG_UNBLOCK, ~[], NULL) = 0

비트셋이 너무 크면 ~[] 형태로 모든 시그널 포함을 나타낸다

마무리

strace는 커널-사용자 인터페이스를 깊이 있게 이해하고 싶은 사람, 버그를 추적하고 싶은 개발자, 혹은 내부 동작이 궁금한 시스템 관리자에게 매우 유용한 도구이다.


📜option

옵션 내 카테고리가 존재하고 엄청 많다. 아래는 몇 개 뽑아서 정리했을 뿐..

1. 기본 사용법

strace [옵션] <명령어>

2. 필터링

-e trace=... 옵션을 사용하면 특정 범주의 시스템 콜만 추적할 수 있다.

  • file: open, read, write, stat 등
  • process: fork, execve, wait 등
  • network: socket, connect 등
  • signal: sigaction, kill 등
# 예시
strace -e trace=file ls
strace -e trace=read,write cat file.txt

3. 요약 통계

  • c: count/statistics: 시스템 요약 통계

4. 실행 중인 프로세스 추척

strace -p <PID>
strace -p 1234 -p 5678 # 여러개
strace -f bash -c 'ls | grep keyword' #오 이렇게 멀티프로세스에 관련된 추적은 
# 묶어줘야 한다..! = 하나의 문자열을 명령어로 해석해서 실행하라.
# bash 뒤에 있는 c는 command의 약자다.

-f: 자식 프로세스 추적

(약간의 응용)

5. 시간 측정 및 타임스탬프

🤔이건 어디에 쓰려나??

-T: 시스템 콜이 소비한 시간 표시
-tt: 시/분/초 단위(절대시간)의 타임스탬프 표시
-ttt: 유닉스 타임스탬프(초 단위) 출력


📜history

원래의 strace는 Paul Kranenburg가 SunOS용으로 작성했으며, 이는 SunOS의 trace 유틸리티에서 영감을 받은 것이었다.
SunOS 버전의 strace는 Branko Lankester가 Linux로 포팅했고, 그는 Linux 커널 지원도 함께 개발했다.
Paul은 1992년에 strace 2.5를 릴리스했지만, Branko의 작업은 1991년에 발표된 strace 1.5를 기반으로 한 것이었다.

1993년에는 Rick Sladkey가 SunOS용 strace 2.5와 두 번째로 릴리스된 Linux용 strace를 통합했고,
SVR4의 truss(1) 유틸리티에서 여러 기능을 추가해 두 플랫폼에서 모두 작동하는 strace를 만들어냈다.
1994년에는 Rick이 strace를 SVR4와 Solaris로 포팅했고, 자동 구성 기능도 작성했다.
1995년에는 Irix로의 포팅도 진행했으며, 이후 Rick은 자기 자신을 3인칭으로 언급하는 것에 질리게 되었다.

1996년부터는 Wichert Akkerman이 strace를 유지 관리하기 시작했다.
그의 관리 아래에서 strace 개발은 CVS로 이전되었고,
FreeBSD와 다양한 Linux 아키텍처(ARM, IA-64, MIPS, PA-RISC, PowerPC, s390, SPARC)로의 포팅이 이루어졌다.

2002년에는 유지 관리의 책임이 Roland McGrath에게 넘어갔다.
그 이후로 strace는 AMD64, s390x, SuperH 등 다양한 Linux 아키텍처에 대한 지원이 추가됐고,
일부 아키텍처에 대해서는 이중 아키텍처 지원도 구현됐다.
또한 Linux 시스템 콜 디코더들이 대폭 개선됐으며, 이 시기에 개발 저장소도 Git으로 이전됐다.

2009년부터는 Dmitry Levin이 strace를 적극적으로 유지 관리하고 있다.
이 시기에는 AArch64, ARC, AVR32, Blackfin, Meta, Nios II, OpenRISC 1000, RISC-V, Tile/TileGx, Xtensa 아키텍처에 대한 지원이 추가됐다.

2012년에는 유지 관리가 중단되었거나 더 이상 작동하지 않는 비-Linux 운영 체제에 대한 지원이 제거됐으며, 같은 해에 경로 추적(path tracing) 및 파일 디스크립터 경로 디코딩 기능이 도입됐다.

2014년에는 스택 추적(stack trace) 출력 기능이 추가됐고,
2016년에는 시스템 콜 오류(fault) 주입 기능이 구현됐다.

자세한 내용은 NEWS 파일과 strace 저장소의 커밋 로그를 참고하면 된다.

모니터링 도구

htop(터미널 기반)

profile
수학을 사랑하는 애독자📚 Stop dreaming. Start living. - 'The Secret Life of Walter Mitty'

0개의 댓글