strace 와 관련된 2번째 글 입니다.


지난번에 이야기 하였듯이 strace는 bin 파일에서, system call 함수를 추적해 볼 수 있는 툴 입니다.


시스템 콜에서 주로 사용하는 옵션에 대하여 알아 보도록 하겠 습니다.


-------------------------------------


-c 각각의 시스템 콜에 대한 시간, 콜 개수, 에러 카운트


# strace -c /bin/ls

COPYING        README           config_20120308    fs       mm                                                              serial_msg_ok_config   usr

CREDITS        REPORTING-BUGS   config_crespo      include  net                                                             serial_msg_ok_config2  virt

Documentation  arch             crypto             init     patch-linux-2.6-samsung-2.6.35-samsung-73a7976-2011.04.17-full  serial_msg_ok_config3

Kbuild         block            drivers            ipc      samples                                                         sound

MAINTAINERS    build.sh         falinux-patch.txt  kernel   scripts                                                         tags

Makefile       config_20120302  firmware           lib      security                                                        tools

% time     seconds  usecs/call     calls    errors syscall

------ ----------- ----------- --------- --------- ----------------

 86.07    0.001427        1427         1           execve

 13.93    0.000231          23        10           mprotect

  0.00    0.000000           0         9           read

  0.00    0.000000           0         6           write

  0.00    0.000000           0        11           open

  0.00    0.000000           0        13           close

  0.00    0.000000           0         9         9 access

  0.00    0.000000           0         3           brk

  0.00    0.000000           0         2           ioctl

  0.00    0.000000           0         3           munmap

  0.00    0.000000           0         1           uname

  0.00    0.000000           0         2           rt_sigaction

  0.00    0.000000           0         1           rt_sigprocmask

  0.00    0.000000           0         1           getrlimit

  0.00    0.000000           0        24           mmap2

  0.00    0.000000           0        11           fstat64

  0.00    0.000000           0         2           getdents64

  0.00    0.000000           0         1           fcntl64

  0.00    0.000000           0         2         1 futex

  0.00    0.000000           0         1           set_thread_area

  0.00    0.000000           0         1           set_tid_address

  0.00    0.000000           0         1           statfs64

  0.00    0.000000           0         1           set_robust_list

------ ----------- ----------- --------- --------- ----------------

100.00    0.001658                   116        10 total


-p pid 프로세스 아이디를 지정 한다.

# ps auxw | grep smb

root       433  0.0  0.2  17108  2392 ?        Ss   09:50   0:00 smbd -F

root       537  0.0  0.1  17108  1100 ?        S    09:50   0:00 smbd -F

root     30570  0.5  0.4  17408  4224 ?        S    12:13   0:03 smbd -F

root     30635  0.0  0.0   4156   860 pts/0    S+   12:24   0:00 grep --color=auto smb


# strace -p 30570

Process 30570 attached - interrupt to quit

select(34, [6 8 29 33], [], NULL, {19, 681092}) = 1 (in [29], left {16, 353723})

gettimeofday({1331781859, 79347}, NULL) = 0

read(29, "\0\0\0T", 4)                  = 4

read(29, "\377SMB2\0\0\0\0\30\7\310\0\0\0\0\0\0\0\0\0\0\0\0\1\0l\4\0\0\3\310"..., 84) = 84

fcntl64(23, F_SETLKW64, {type=F_RDLCK, whence=SEEK_SET, start=416, len=1}, 0xbfe2d308) = 0

fcntl64(23, F_SETLKW64, {type=F_UNLCK, whence=SEEK_SET, start=416, len=1}, 0xbfe2d368) = 0

fcntl64(23, F_SETLKW64, {type=F_RDLCK, whence=SEEK_SET, start=416, len=1}, 0xbfe2d308) = 0

fcntl64(23, F_SETLKW64, {type=F_UNLCK, whence=SEEK_SET, start=416, len=1}, 0xbfe2d368) = 0

geteuid32()                             = 0

getegid32()                             = 0

setgroups32(1, [65534])                 = 0

setregid32(-1, 65534)                   = 0

getegid32()                             = 65534

setreuid32(-1, 65534)                   = 0

geteuid32()                             = 65534

stat64("dev", {st_mode=S_IFDIR|0755, st_size=4080, ...}) = 0

getcwd("/", 4096)                       = 2

lstat64("/dev", {st_mode=S_IFDIR|0755, st_size=4080, ...}) = 0

fcntl64(14, F_SETLKW64, {type=F_RDLCK, whence=SEEK_SET, start=14672, len=1}, 0xbfe2d148) = 0

fcntl64(14, F_SETLKW64, {type=F_UNLCK, whence=SEEK_SET, start=14672, len=1}, 0xbfe2d1a8) = 0

... ( 생략 ) ...


-r 각 시스템 콜에 대한 엔트리 상의 관련 타임 스탬프를 출력 한다. 이는 성공한 시스템 콜들이 시작된 시간 사이의 시간차를 기록 한다.

# strace -t -r /bin/ls

     0.000000 execve("/bin/ls", ["/bin/ls"], [/* 15 vars */]) = 0

     0.007983 brk(0)                    = 0x8d23000

     0.001686 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

     0.001442 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb78fc000

     0.001841 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)

     0.000803 open("/etc/ld.so.cache", O_RDONLY) = 3

     0.000884 fstat64(3, {st_mode=S_IFREG|0644, st_size=17524, ...}) = 0

     0.001616 mmap2(NULL, 17524, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb78f7000

     0.000372 close(3)                  = 0

     0.000905 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

     0.000884 open("/lib/i386-linux-gnu/libselinux.so.1", O_RDONLY) = 3

     0.000682 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300>\0\0004\0\0\0"..., 512) = 512

     0.001753 fstat64(3, {st_mode=S_IFREG|0644, st_size=104116, ...}) = 0

     0.001195 mmap2(NULL, 109440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb49000

     0.000377 mmap2(0xb62000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x18) = 0xb62000

     0.000749 close(3)                  = 0

     0.001361 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

     0.000570 open("/lib/i386-linux-gnu/librt.so.1", O_RDONLY) = 3

     0.000643 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\30\0\0004\0\0\0"..., 512) = 512

     0.000705 fstat64(3, {st_mode=S_IFREG|0644, st_size=30684, ...}) = 0

     0.001379 mmap2(NULL, 33364, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xfab000

     0.000379 mmap2(0xfb2000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6) = 0xfb2000

     0.001575 close(3)                  = 0

     0.000471 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

     0.000689 open("/lib/i386-linux-gnu/libacl.so.1", O_RDONLY) = 3

     0.001073 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\260\23\0\0004\0\0\0"..., 512) = 512

     0.001136 fstat64(3, {st_mode=S_IFREG|0644, st_size=26124, ...}) = 0

     0.001137 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb78f6000

     0.000488 mmap2(NULL, 28964, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x947000

     0.000413 mmap2(0x94d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x5) = 0x94d000

     0.001777 close(3)                  = 0

     ... ( 중간 생략 ) ...

     0.000888 close(1)                  = 0

     0.000369 munmap(0xb78fb000, 4096)  = 0

     0.000471 close(2)                  = 0

     0.000967 exit_group(0)             = ?


-t 각 라인에 시간을 출력 한다.

# strace -t /bin/echo

12:19:03 execve("/bin/echo", ["/bin/echo"], [/* 15 vars */]) = 0

12:19:03 brk(0)                         = 0x865e000

12:19:03 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

12:19:03 mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7771000

12:19:03 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)

12:19:03 open("/etc/ld.so.cache", O_RDONLY) = 3

12:19:03 fstat64(3, {st_mode=S_IFREG|0644, st_size=17524, ...}) = 0

12:19:03 mmap2(NULL, 17524, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb776c000

12:19:03 close(3)                       = 0

12:19:03 access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)

12:19:03 open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3

12:19:03 read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\220o\1\0004\0\0\0"..., 512) = 512

12:19:03 fstat64(3, {st_mode=S_IFREG|0755, st_size=1434180, ...}) = 0

12:19:03 mmap2(NULL, 1444360, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x717000

12:19:03 mprotect(0x871000, 4096, PROT_NONE) = 0

12:19:03 mmap2(0x872000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15a) = 0x872000

12:19:03 mmap2(0x875000, 10760, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x875000

12:19:03 close(3)                       = 0

12:19:03 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb776b000

12:19:03 set_thread_area({entry_number:-1 -> 6, base_addr:0xb776b8d0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0

12:19:03 mprotect(0x872000, 8192, PROT_READ) = 0

12:19:03 mprotect(0x804d000, 4096, PROT_READ) = 0

12:19:03 mprotect(0xcb0000, 4096, PROT_READ) = 0

12:19:03 munmap(0xb776c000, 17524)      = 0

12:19:03 brk(0)                         = 0x865e000

12:19:03 brk(0x867f000)                 = 0x867f000

12:19:03 open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3

12:19:03 fstat64(3, {st_mode=S_IFREG|0644, st_size=2781408, ...}) = 0

12:19:03 mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb756b000

12:19:03 close(3)                       = 0

12:19:03 fstat64(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 0), ...}) = 0

12:19:03 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7770000

12:19:03 write(1, "\n", 1

)              = 1

12:19:03 close(1)                       = 0

12:19:03 munmap(0xb7770000, 4096)       = 0

12:19:03 close(2)                       = 0

12:19:03 exit_group(0)                  = ?


-e 특정 시스템 콜을 지정하여 출력 한다.

# strace -e trace=open /bin/echo

open("/etc/ld.so.cache", O_RDONLY)      = 3

open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3

open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3


-c -S sortby 옵션과 함께 사용되며 특정 컬럼을 정렬할 수 있다.  특정 컬럼값에는 time, calls, name 등으로 가능하다.


# strace -c -S name /bin/echo

% time     seconds  usecs/call     calls    errors syscall

------ ----------- ----------- --------- --------- ----------------

  0.00    0.000000           0         3         3 access

  0.00    0.000000           0         3           brk

  0.00    0.000000           0         5           close

 90.66    0.002999        2999         1           execve

  0.00    0.000000           0         4           fstat64

  0.00    0.000000           0         8           mmap2

  9.34    0.000309          77         4           mprotect

  0.00    0.000000           0         2           munmap

  0.00    0.000000           0         3           open

  0.00    0.000000           0         1           read

  0.00    0.000000           0         1           set_thread_area

  0.00    0.000000           0         1           write

------ ----------- ----------- --------- --------- ----------------

100.00    0.003308                    36         3 total


# strace -c -S time /bin/echo


% time     seconds  usecs/call     calls    errors syscall

------ ----------- ----------- --------- --------- ----------------

 90.32    0.002369        2369         1           execve

  9.68    0.000254         127         2           munmap

  0.00    0.000000           0         1           read

  0.00    0.000000           0         1           write

  0.00    0.000000           0         3           open

  0.00    0.000000           0         5           close

  0.00    0.000000           0         3         3 access

  0.00    0.000000           0         3           brk

  0.00    0.000000           0         4           mprotect

  0.00    0.000000           0         8           mmap2

  0.00    0.000000           0         4           fstat64

  0.00    0.000000           0         1           set_thread_area

------ ----------- ----------- --------- --------- ----------------

100.00    0.002623                    36         3 total