9.11 strace:跟踪进程的系统调用 、ltrace:跟踪进程调用库函数
strace
是Linux环境下的一款程序调试工具,用于检查一个应用程序所使用的系统调用以及它所接收的系统信息。strace会追踪程序运行时的整个生命周期,输出每一个系统调用的名字、参数、返回值和执行所消耗的时间等,是高级运维和开发人员排查问题的杀手铜。
strace命令的参数选项及说明
-c 统计每一个系统调用所执行的时间、次数和出错的次数等 -d 输出strace关于标准错误的调试信息 -f 跟踪目标进程,以及目标进程创建的所有子进程 -ff 如果提供-o filename,则将所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号 -i 输出系统调用的入口指针 -q 禁止输出关于脱离的消息 -r 输出每一个系统调用的相对时间 -t 在输出中的每一行前加上时间信息。例如16:45:28 -tt 在输出中的每一行前加上时间信息,精确到微秒。例如11:18:59.759546端 -ttt 在输出中的每一行前加上时间信息,精确到微秒,而且时间表示为UNIX时间戳。例如1486111461.650434 -T 显示每次系统调用所花费的时间 -v 对于某些相关调用,把完整的环境变量、文件stat结构等打印出来 -x 以十六进制形式输出非标准字符率 -xx 所有字符串以十六进制形式输出 -e expr 输出过滤器,通过表达式,可以过滤掉你不想要的输出 expr是一个表达式,用于控制如何跟踪:[qualifier=][!][valuel[,value2].. 说明: ①qualifier 只能是trace、abbrev、verbose、raw、signal、read、write其中之一 ②value是用来限定的符号或数字 ③默认的qualifier是trace ④感叹号是否定符号 例如: -e open等价于-e trace=open,表示只跟踪open调用 而-e trace!=open表示跟踪除了open以外的其他调用 常见选项: -e trace=[set] 只跟踪指定的系统调用 -e trace=file 只跟踪与文件操作有关的系统调用 -e trace=process 只跟踪与进程控制有关的系统调用 -e trace-network 只跟踪与网络有关的系统调用 -e trace=signal 只跟踪与系统信号有关的系统调用 -e trace=desc 只跟踪与文件描述符有关的系统调用 -e trace=ipc 只跟踪与进程通信有关的系统调用 -e abbrev=[set] 设定strace输出的系统调用的结果集 -e raw=[set] 将指定的系统调用的参数以十六进制显示 -e signal=[set] 指定跟踪的系统信号 -e read=[set] 输出从指定文件中读出的数据 -e write=[set] 输出写入到指定文件中的数据 -o filename 将strace的输出写入文件filename -p pid 指定要跟踪的进程pid,要同时跟踪多个pid,重复多次p选项即可* -s strsize 指定输出的字符串的最大长度,默认为32。并没有将文件名视为字符串,默认全部输出 -u username 以usemame的UID和GID执行所跟踪的命令
排查Nginx403 forbidden错误
strace -tt -f /applicatton/nginx/sbin/nginx
只跟踪与文件操作有关的系统调用
strace -tt -f -e trace=file /application/nginx/sbin/nginx #只跟综与文件操作有关的系统调用。
通过pid 跟踪进程
[root@bzhl ~]# pgrep nginx
1884
7785
7786
7787
[root@bzhl ~]# pstree -p 1884
nginx(1884)─┬─nginx(7785)
├─nginx(7786)
└─nginx(7787)
[root@bzhl ~]# strace -tt -f -e trace=file -p 7785
strace: Process 7785 attached
跟踪系统调用统计
strace不仅能够追踪系统调用,使用选项-c还能对进程所有的系统调用做一个统计分析。
[root@bzhl ~]# which nginx /usr/bin/nginx [root@bzhl ~]# strace -c /usr/bin/nginx % time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 22.33 0.001129 7 153 52 open 15.55 0.000786 6 123 close 10.80 0.000546 6 95 mmap 8.53 0.000431 13 32 write 7.66 0.000387 10 39 read 6.47 0.000327 7 48 mprotect 5.38 0.000272 12 22 munmap 4.35 0.000220 3 87 fstat 3.20 0.000162 32 5 nanosleep 2.87 0.000145 8 19 socket 2.67 0.000135 4 38 pread64 2.29 0.000116 29 4 4 connect 1.19 0.000060 4 15 15 bind 1.03 0.000052 3 16 5 stat 1.03 0.000052 9 6 getdents 0.99 0.000050 3 15 setsockopt 0.65 0.000033 11 3 openat 0.63 0.000032 2 15 ioctl 0.63 0.000032 5 6 6 mkdir 0.47 0.000024 2 12 fcntl 0.16 0.000008 8 1 statfs 0.14 0.000007 7 1 1 readlink 0.10 0.000005 5 1 epoll_create 0.08 0.000004 2 2 rt_sigaction 0.08 0.000004 2 2 uname 0.08 0.000004 2 2 gettimeofday 0.08 0.000004 4 1 futex 0.06 0.000003 3 1 poll 0.06 0.000003 3 1 lseek 0.06 0.000003 2 2 getrlimit 0.06 0.000003 3 1 getppid 0.06 0.000003 3 1 sched_getaffinity 0.04 0.000002 1 2 brk 0.04 0.000002 2 1 rt_sigprocmask 0.04 0.000002 2 1 getuid 0.04 0.000002 2 1 arch_prctl 0.04 0.000002 2 1 set_tid_address 0.04 0.000002 2 1 set_robust_list 0.02 0.000001 1 1 geteuid 0.00 0.000000 0 1 1 access 0.00 0.000000 0 1 execve ------ ----------- ----------- --------- --------- ---------------- 100.00 0.005055 779 84 total
上面的结果将清楚地告诉我们调用了哪些系统函数,调用的次数是多少,消耗了多少时间等信息,这对我们分析程序来说是非常有用的。
重定向输出。
strace -c -o tongji.log /application/nginx/sbin/nginx #用 -o 选项将strace的结果输出到文件中
对系统调用进行计时
strace -T /application/nginx/sbin/ngirnx #<=使用选项-T将每个系统调用所花费的时间打印出来,每个调用的时间花费在调用行最右边的尖括导里面。
小结:strace命令很适合处埋程序僵尸、命令执行报错等问题,如果从程序日志和系统日志中看不出问题出现的原因,则可以strace一下,也许会有答案,不过也需要使用者有足够的耐心去查看输出!
ltrace:跟踪进程调用库函数
ltrace 能够跟踪进程的库函数调用,它会显现出调用了哪个库函数,而 strace则是跟踪进程的每个系统调用。
ltrace命令的参数选项及说明
-c 统计库函数每次调用的时间,最后程序退出时打印摘要 -C 解码低级别名称(内核级)为用户级名称 -d 打印调试信息 -e expr 输出过滤器,通过表达式,可以过滤掉你不想要的输出 -e printf 表示只查看printf函数调用 -e !printf 表示查看除printf函数以外的所有函数调用 -f 跟踪子进程 -o filename 将ltrace的输出写入文件filename -p pid 指定要跟踪的进程pid -r 输出每一个调用的相对时间 -S 显示系统调用 -t 在输出中的每一行前加上时间信息。例如16:45:28 -tt 在输出中的每一行前加上时间信息,精确到微秒。例如11:18:59.759546 -ttt 在输出中的每一行前加上时间信息,精确到微秒,而且时间表示为UNIX时间截。例如1486111461.650434 -T 显示每次调用所花费的时间 -u username 以username的UID和GID执行所跟踪的命令
Itrace使用
ltrace的用法与strace非常相似,选项功能也是类似
[root@bzhl ~]# ltrace /usr/bin/nginx
通过pid 跟踪进程调用库函数。
[root@bzhl ~]# pgrep nginx
1884
7785
7786
7787
[root@bzhl ~]# ltrace -p 1884