본문으로 건너뛰기

strace 명령어로 시스템 콜 추적하는 방법은 무엇인가요?

💡 요약 정리

  • strace는 리눅스에서 실행 중인 명령어 또는 프로세스를 시스템 콜 수준에서 추적할 수 있는 도구입니다.
  • -o, -c, -T 옵션을 활용하면 결과를 파일로 저장하거나 통계, 시간 정보를 수집할 수 있습니다.
  • 특정 PID를 지정하여 실행 중인 프로세스의 실시간 시스템 콜을 추적하는 것도 가능합니다.

strace는 프로그램이 실행될 동안 호출하는 시스템 콜을 추적할 수 있는 툴입니다.


1. ls 명령을 실행할 때 호출되는 시스템 콜 확인

[root@localhost web]# strace ls
execve("/bin/ls", ["ls"], [/* 22 vars */]) = 0
brk(0)                                 = 0x85aa000
access("/etc/ld.so.preload", R_OK)    = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)    = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=38402, ...}) = 0
mmap2(NULL, 38402, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7ff6000
close(3)                               = 0
open("/lib/librt.so.1", O_RDONLY)     = 3
read(3, "177ELF111\0\0\0...", 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=42048, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7ff5000
mmap2(NULL, 33324, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x21a000
mmap2(0x221000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6) = 0x221000
close(3)                               = 0
open("/lib/libacl.so.1", O_RDONLY)    = 3
...
[root@localhost web]#

2. 시스템 콜 호출 결과를 파일로 저장

[root@localhost ~]# strace -o ls_sresult.txt ls
anaconda-ks.cfg  clear.txt  Desktop  http_install  install.log  ls_sresult.txt
check.sh         cleat.txt  httpd.conf  HW_result_localhost  install.log.syslog  soft.sh
[root@localhost ~]#

3. -c 옵션을 이용한 시스템 콜 통계 작성

[root@localhost ~]# strace -o ls_sresult2.txt -c ls
[root@localhost ~]# cat ls_sresult2.txt
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
  82.89    0.001260      1260          1           execve
   9.74    0.000148         5         27           mmap2
   7.37    0.000112        14          8           close
   0.00    0.000000        12          0           read
   0.00    0.000000         2          0           write
   0.00    0.000000        13          0           open
   0.00    0.000000         2          1           access
   0.00    0.000000         3          0           brk
   0.00    0.000000         2          0           ioctl
   0.00    0.000000         4          0           munmap
   0.00    0.000000         1          0           uname
   ...
------ ----------- ----------- --------- --------- ----------------
100.00    0.001520                   111           total
[root@localhost ~]#

4. -T 옵션을 추가하여 각 시스템 콜의 실행 시간 확인

[root@localhost ~]# strace -o ls_sresult3.txt -T ls
[root@localhost ~]# cat ls_sresult3.txt
execve("/bin/ls", ["ls"], [/* 22 vars */]) = 0 <0.001162>
brk(0)                                 = 0x8f62000 <0.000030>
access("/etc/ld.so.preload", R_OK)    = -1 ENOENT (No such file or directory) <0.000038>
open("/etc/ld.so.cache", O_RDONLY)    = 3 <0.000084>
fstat64(3, {st_mode=S_IFREG|0644, st_size=38402, ...}) = 0 <0.000029>
mmap2(NULL, 38402, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f26000 <0.000035>
...
[root@localhost web]#

5. 디렉토리를 tar로 압축하는 동안 호출되는 시스템 콜 추적

[root@localhost web]# strace -o result.txt -T tar cvzfp apache.tar.gz apache/
[root@localhost web]# cat result.txt
execve("/bin/tar", ["tar", "cvzfp", "apache.tar.gz", "apache/"], [/* 22 vars */]) = 0 <0.001038>
brk(0)                                 = 0x9d3e000 <0.000031>
access("/etc/ld.so.preload", R_OK)    = -1 ENOENT (No such file or directory) <0.000038>
open("/etc/ld.so.cache", O_RDONLY)    = 3 <0.000039>
fstat64(3, {st_mode=S_IFREG|0644, st_size=38402, ...}) = 0 <0.000030>
...
[root@localhost web]#

6. 현재 수행 중인 프로세스에 대한 시스템 콜 확인

① 실행 중인 bash 프로세스 확인

[root@localhost /]# ps ax | grep bash
4182 pts/1    Ss    0:00 bash
5685 pts/2    Ss    0:00 bash
7832 pts/2    R+    0:00 grep bash

② pts/1에서 strace로 추적 시작

[root@localhost /]# strace -p 5685
Process 5685 attached - interrupt to quit
read(0,

③ pts/2에서 명령어 실행 시 pts/1에 실시간 기록되는 시스템 콜 확인

[root@localhost jook]# strace -p 5685
Process 5685 attached - interrupt to quit
read(0, "l", 1)                          = 1
write(2, "l", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "s", 1)                          = 1
write(2, "s", 1)                         = 1
...
[root@localhost jook]#

이와 같이 실시간으로 특정 PID의 시스템 콜을 추적하는 데에도 strace를 활용할 수 있습니다.