0%

strace

跟踪系统调用和信号的工具。

strace命令是一个集诊断、调试、统计于一体的工具,使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析 ,以达到解决问题或者了解应用工作过程的目的。有时错误日志不能满足定位问题的需求,因此需要从更“深层”的方面着手分析,可以通过strace观察这些系统调用及其参数、返回值,界定出错的范围,甚至找出问题出现的根因。

strace工具的用途:

  • 可以对特定的系统调用或者几组系统调用进行过滤

  • 可以通过统计特定系统调用的调用次数、耗费的时间、成功和失败的次数来配置(profile)系统调用的使用

  • 可以跟踪发送给进程的信号量

  • 可以通过pid附着(attach)到任何运行的进程

Linux内核目前有300多个系统调用,详细的列表可以通过syscalls手册页查看。这些系统调用主要分为几类:

  • 文件和设备访问类 比如open/close/read/write/chmod等

  • 进程管理类 fork/clone/execve/exit/getpid等

  • 信号类 signal/sigaction/kill 等

  • 内存管理 brk/mmap/mlock等

  • 进程间通信 IPC shmget/semget * 信号量,共享内存,消息队列等

  • 网络通信 socket/connect/sendto/sendmsg 等

  • 其他

strace运行模式

启动并跟踪进程

1
2
3
4
5
6
7
8
9
# strace /usr/local/webserver/php-7.2.5/sbin/php-fpm  2>&1 | less
...
access("/usr/local/webserver/php-7.2.5/sbin/php-fpm", X_OK) = 0
open("/usr/local/webserver/php-7.2.5/sbin/php-fpm-fcgi.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/local/webserver/php-7.2.5/etc/php-fpm-fcgi.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/local/webserver/php-7.2.5/sbin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/local/webserver/php-7.2.5/etc/php.ini", O_RDONLY) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0x7fff4df60df0) = -1 ENOTTY (Inappropriate ioctl for device)
...

strace会将输出以标准错误的方式输出,故这里使用了2>&1以保证这些输出可以被less捕获到。一额可以使用-o参数将输出重定向到文件,但需要注意strace的参数应该在被调用的命令左侧。

1
2
3
# strace -o /tmp/strace_php /usr/local/webserver/php-7.2.5/sbin/php-fpm 
# ll -h /tmp/strace_php
-rw-r--r-- 1 root root 1.1M Dec 14 11:24 /tmp/strace_php

跟踪正在运行的进程

1
2
3
4
5
6
7
8
9
10
11
12
# pidof some_server
1571
# strace -p 1571
Process 1571 attached - interrupt to quit
epoll_wait(8, {}, 201, 455) = 0
getsockopt(7, SOL_TCP, TCP_INFO, "\n\0\0\0\0\0\0\0@B\17\0\0\0\0\0\30\2\0\0\0\0\0\0\0\0\0\0\200\0\0\0"..., [104]) = 0
epoll_wait(8, {}, 201, 1000) = 0
getsockopt(7, SOL_TCP, TCP_INFO, "\n\0\0\0\0\0\0\0@B\17\0\0\0\0\0\30\2\0\0\0\0\0\0\0\0\0\0\200\0\0\0"..., [104]) = 0
epoll_wait(8, {}, 201, 1000) = 0
getsockopt(7, SOL_TCP, TCP_INFO, "\n\0\0\0\0\0\0\0@B\17\0\0\0\0\0\30\2\0\0\0\0\0\0\0\0\0\0\200\0\0\0"..., [104]) = 0
epoll_wait(8, {}, 201, 1000)
...

跟踪并统计system call

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# strace -fc -p 14273
...
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
40.73 112.980862 252189 448 recvfrom
40.04 111.062437 5797 19158 8597 futex
14.95 41.461777 50318 824 epoll_wait
2.15 5.973067 36871 162 156 restart_syscall
0.44 1.233828 2172 568 write
0.42 1.165822 3185 366 64 read
0.38 1.056849 2928 361 epoll_ctl
0.23 0.642915 2613 246 sendto
0.11 0.299869 477 629 sched_yield
0.08 0.232967 3106 75 poll
0.07 0.184972 2890 64 setsockopt
0.06 0.179976 2337 77 fcntl
0.06 0.173975 1933 90 ioctl
0.03 0.095002 979 97 rt_sigprocmask
...

strace常用参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-c 统计每一系统调用的所执行的时间,次数和出错的次数等. 
-d 输出strace关于标准错误的调试信息.
-f 除了跟踪当前进程外,还跟踪由fork调用所产生的子进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针寄存器值.
-q 禁止输出关于结合(attaching)、脱离(detaching)的消息,当输出重定向到一个文件时,自动抑制此类消息.
-r 打印出相对时间关于每一个系统调用,即连续的系统调用起点之间的时间差,与-t对应.
-t 打印各个系统调用被调用时的绝对时间秒级,观察程序各部分的执行时间可以用此选项。
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 在每行输出前添加相对时间信息,格式为”自纪元时间起经历的秒数.微秒数”
-T 显示每一调用所耗的时间,其时间开销在输出行最右侧的尖括号内.
-v 冗余显示模式:显示系统调用中argv[]envp[]stat、termio(s)等数组/结构体参数所有的元素/成员内容.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串 。
-xx 所有字符串以十六进制形式输出.
-a column 设置返回值的输出位置.默认为40,即"="出现在第40列.
-e expr 指定一个表达式,用来控制如何跟踪.
-e trace=set 只跟踪指定的系统 调用.例如:-e trace=open.
-e trace=file 只跟踪有关文件操作的系统调用.
-e trace=process 只跟踪有关进程控制的系统调用.
-e trace=network 跟踪与网络有关的所有系统调用.
-e trace=signal 跟踪所有与系统信号有关的 系统调用
-e trace=ipc 跟踪所有与进程通讯有关的系统调用
-e abbrev=set 设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set 将指 定的系统调用的参数以十六进制显示.
-e signal=set 指定跟踪的系统信号.默认为all.如signal=!SIGIO,表示不跟踪SIGIO信号.
-e read=set 输出从指定文件中读出 的数据.例如: -e read=3,5 -e write=set
-E var 从命令的环境变量列表中移除var。
-E var=val 将var=val放入命令的环境变量列表.
-o filename 将strace的输出写入文件filename,而不是显示到标准错误输出(stderr).
-p pid 跟踪指定的进程pid,可指定多达32个(-p pid)选项以同时跟踪多个进程。该选项常用于调试后台进程.
-s strsize 限制每行输出中字符串(如read参数)的最大显示长度,默认32字节。但文件名总是完整显示
-S sortby 按指定规则对-c选项的输出直方图进行排序。sortby取值可为time、calls、name和nothing(默认 time)
-u username 以username 的UID和GID执行被跟踪的命令

更多系统调用表请访问
https://blog.csdn.net/Huangxiang6/article/details/81295752

参考:
https://blog.csdn.net/Huangxiang6/article/details/81295752