strace命令用来跟踪给定程序的系统调用和接受到的signal,主要是在unix类的操作系统上
yum install strace
strace的man page的解释是: trace system calls and signals
strace用来调试和排查程序进行系统调用的相关细节信息,用于排查程序异常执行情况的利器.
常用的命令是直接加上待运行的命令,或者直接 -p 加上待跟踪程序的pid
例如:
strace ls -al
strace -p 1223
strace命令可以指定参数支持其他功能,常用功能如下:
统计所有系统调用的情况
[root@104 ~]# strace -c -p 9117
strace: Process 9117 attached
^Cstrace: Process 9117 detached
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
21.91 0.000039 7 6 close
19.66 0.000035 18 2 2 connect
12.36 0.000022 6 4 write
10.11 0.000018 2 8 epoll_wait
8.43 0.000015 5 3 writev
8.43 0.000015 8 2 socket
6.18 0.000011 3 4 accept4
5.06 0.000009 1 7 epoll_ctl
2.81 0.000005 5 1 open
1.69 0.000003 1 3 recvfrom
1.12 0.000002 1 2 ioctl
0.56 0.000001 1 1 fstat
0.56 0.000001 1 1 readv
0.56 0.000001 1 1 setsockopt
0.56 0.000001 1 1 getsockopt
0.00 0.000000 0 2 gettid
------ ----------- ----------- --------- --------- ----------------
100.00 0.000
输出系统调用时程序指令的地址(instruction pointer)
[root@104 ~]# strace -i -p 9117
strace: Process 9117 attached
[00007f28f2340903] epoll_wait(11, [{EPOLLIN, {u32=1713088536, u64=93876813277208}}], 512, -1) = 1
[00007f28f2341787] accept4(6, {sa_family=AF_INET, sin_port=htons(35984), sin_addr=inet_addr("104.224.143.127")}, [16], SOCK_NONBLOCK) = 4
[00007f28f23408ca] epoll_ctl(11, EPOLL_CTL_ADD, 4, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=1713089280, u64=93876813277952}}) = 0
[00007f28f2340903] epoll_wait(11, [{EPOLLIN, {u32=1713088536, u64=93876813277208}}], 512, 60000) = 1
[00007f28f2341787] accept4(6, {sa_family=AF_INET, sin_port=htons(35986), sin_addr=inet_addr("104.224.143.127")}, [16], SOCK_NONBLOCK) = 5
[00007f28f23408ca] epoll_ctl(11, EPOLL_CTL_ADD, 5, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=1713089528, u64=93876813278200}}) = 0
[00007f28f2340903] epoll_wait(11, [{EPOLLIN, {u32=1713088536, u64=93876813277208}}], 512, 60000) = 1
[00007f28f2341787] accept4(6, {sa_family=AF_INET, sin_port=htons(35988), sin_addr=inet_addr("104.224.143.127")}, [16], SOCK_NONBLOCK) = 8
...
输出系统调用发生的时间
[root@104 ~]# strace -t -p 9117
strace: Process 9117 attached
01:57:52 epoll_wait(11, [{EPOLLIN|EPOLLRDHUP, {u32=1713089528, u64=93876813278200}}], 512, 17389) = 1
01:58:01 recvfrom(5, "", 1024, 0, NULL, NULL) = 0
01:58:01 close(5) = 0
01:58:01 epoll_wait(11, [{EPOLLIN|EPOLLRDHUP, {u32=1713089280, u64=93876813277952}}], 512, 8584) = 1
01:58:01 recvfrom(4, "", 1024, 0, NULL, NULL) = 0
01:58:01 close(4) = 0
01:58:01 epoll_wait(11, [{EPOLLIN|EPOLLOUT, {u32=1713089032, u64=93876813277704}}], 512, 13581) = 1
01:58:01 recvfrom(8, "GET /index.html HTTP/1.1\r\nHost: "..., 1024, 0, NULL, NULL) = 544
01:58:01 socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 4
01:58:01 ioctl(4, FIONBIO, [1]) = 0
01:58:01 epoll_ctl(11, EPOLL_CTL_ADD, 4, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=1713089281, u64=93876813277953}}) = 0
01:58:01 connect(4, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
01:58:01 epoll_wait(11, [{EPOLLOUT, {u32=1713089281, u64=93876813277953}}, {EPOLLIN, {u32=1713088288, u64=93876813276960}}], 512, 60000) = 2
01:58:01 getsockopt(4, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
01:58:01 writev(4, [{"GET /index.html HTTP/1.0\r\nHost: "..., 537}], 1) = 537
01:58:01 accept4(10, {sa_family=AF_INET, sin_port=htons(45194), sin_addr=inet_addr("127.0.0.1")}, [16], SOCK_NONBLOCK) = 5
01:58:01 epoll_ctl(11, EPOLL_CTL_ADD, 5, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=1713089529, u64=93876813278201}}) = 0
01:58:01 epoll_wait(11, [{EPOLLIN, {u32=1713089529, u64=93876813278201}}], 512, 60000) = 1
01:58:01 recvfrom(5, "GET /index.html HTTP/1.0\r\nHost: "..., 1024, 0, NULL, NULL) = 537
01:58:01 open("/data/www/index.html", O_RDONLY|O_NONBLOCK) = 14
01:58:01 fstat(14, {st_mode=S_IFREG|0644, st_size=95, ...}) = 0
01:58:01 writev(5, [{"HTTP/1.1 304 Not Modified\r\nServe"..., 174}], 1) = 174
01:58:01 write(7, "127.0.0.1 - - [01/Feb/2020:01:58"..., 197) = 197
01:58:01 close(14) = 0
01:58:01 close(5) = 0
01:58:01 epoll_wait(11, [{EPOLLIN|EPOLLOUT|EPOLLRDHUP, {u32=1713089281, u64=93876813277953}}], 512, 60000) = 1
01:58:01 recvfrom(4, "HTTP/1.1 304 Not Modified\r\nServe"..., 4096, 0, NULL, NULL) = 174
01:58:01 readv(4, [{"", 3922}], 1) = 0
01:58:01 close(4) = 0
01:58:01 writev(8, [{"HTTP/1.1 304 Not Modified\r\nServe"..., 179}], 1) = 179
01:58:01 write(7, "104.224.143.127 - - [01/Feb/2020"..., 203) = 203
01:58:01 epoll_wait(11, [{EPOLLIN, {u32=1713088536, u64=93876813277208}}], 512, 65000) = 1
01:58:05 accept4(6, {sa_family=AF_INET, sin_port=htons(35994), sin_addr=inet_addr("104.224.143.127")}, [16], SOCK_NONBLOCK) = 4
01:58:05 epoll_ctl(11, EPOLL_CTL_ADD, 4, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=1713089280, u64=93876813277952}}) = 0
指定仅跟踪指定系统调用.
格式为: strace -e trace=系统调用1,系统调用2 -p pid1
[root@104 ~]# strace -e trace=write -p 9117
strace: Process 9117 attached
write(7, "127.0.0.1 - - [01/Feb/2020:02:01"..., 198) = 198
write(7, "223.104.37.237 - - [01/Feb/2020:"..., 203) = 203
write(7, "223.104.37.237 - - [01/Feb/2020:"..., 235) = 235
write(3, "2020/02/01 02:01:41 [error] 9117"..., 305) = 305
write(3, "2020/02/01 02:01:41 [warn] 9117#"..., 298) = 298
....
重定向strace的输出到给定的文件,注意程序本身的输出不搭嘎
[root@104 ~]# strace -o ls-strace.log ls -al
total 2920
dr-xr-x---. 6 root root 4096 Feb 1 02:05 .
dr-xr-xr-x. 20 root root 4096 Jan 31 07:52 ..
-rw-r--r-- 1 root root 12 Dec 12 23:37 1.html
-rw-r--r-- 1 root root 1096741 Sep 30 2014 1.jpg
-rw-r--r-- 1 root root 422 Jan 31 22:20 1.txt
-rw-------. 1 root root 12694 Feb 1 01:26 .bash_history
-rw-r--r--. 1 root root 18 Dec 28 2013 .bash_logout
-rw-r--r--. 1 root root 176 Dec 28 2013 .bash_profile
-rw-r--r--. 1 root root 176 Dec 28 2013 .bashrc
drwxr-xr-x 3 root root 4096 Nov 13 00:07 .cache
-rw-r--r--. 1 root root 100 Dec 28 2013 .cshrc
-rw-r--r-- 1 root root 1775835 Nov 13 00:07 get-pip.py
-rw-r--r-- 1 root root 12 Jul 5 2018 .kiwivm-sr-encryption
-rw-r--r-- 1 root root 10 Jul 5 2018 .kiwivm-sr-password
-rw-r--r-- 1 root root 4 Jul 5 2018 .kiwivm-sr-port
drwxr-xr-x. 2 root root 4096 Jul 5 2018 .kiwivm-task
-rw------- 1 root root 61 Feb 1 02:04 .lesshst
-rw-r--r-- 1 root root 16279 Feb 1 02:05 ls-strace.log
-rw------- 1 root root 1963 Feb 1 01:58 nohup.out
drwxr-xr-x 2 root root 4096 May 22 2018 .oracle_jre_usage
drwxr-----. 3 root root 4096 Mar 13 2017 .pki
-rwxr-xr-x 1 root root 67 Oct 31 11:34 start.sh
-rw-r--r--. 1 root root 129 Dec 28 2013 .tcshrc
-rw------- 1 root root 1293 Mar 5 2018 .viminfo
[root@104 ~]# cat ls-strace.log
execve("/usr/bin/ls", ["ls", "-al"], [/* 21 vars */]) = 0
brk(NULL) = 0x152d000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5b660a7000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=28975, ...}) = 0
mmap(NULL, 28975, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5b6609f000
close(3) = 0
open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\320i\0\0\0\0\0\0"..., 832) = 832
...省略
strace的debug模式开关,开启后输出strace相关详细日志
[root@104 ~]# strace -d -e trace=write -p 9117
strace: new tcb for pid 9117, active tcbs:1
strace: ptrace_setoptions = 0x11
strace: attach to pid 9117 (main) succeeded
strace: Process 9117 attached
strace: [wait(0x80057f) = 9117] WIFSTOPPED,sig=SIGTRAP,EVENT_STOP (128)
strace: pid 9117 has TCB_STARTUP, initializing it
strace: [wait(0x00857f) = 9117] WIFSTOPPED,sig=133
strace: [wait(0x00857f) = 9117] WIFSTOPPED,sig=133
strace: [wait(0x00857f) = 9117] WIFSTOPPED,sig=133