使用 strace 排查故障

很多情况下,通过日志能够定位大部分问题,遇到性能等问题时仅仅依靠日志和分析代码逻辑往往不够用,这时需要借助系统调用工具来帮助排查。

strace 是什么?
在 Linux 世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等)时,必须由用户态模式切换至内核态模式,通过系统调用接口访问硬件设备。strace 可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。

接下来,跟踪几个进程的调用情况,用 top 查看占用 CPU 高的进程,拿到 PID。
小技巧:输入 top,按 1 查看全部 CPU 的使用情况,shift + p 根据 CPU 排序。

top

我们就来看看 PID=202 进程的系统调用

1
strace -p 202

得到的是满屏的输出字符,不好看出是哪个进程出的问题,如果按调用时间汇总,那会好很多

1
strace -cp 202

按调用时间汇总,得到清晰的结果大致如下:

strace-2

可以看出是 write 使用了大部分的 CPU 操作,我们来单独跟踪 write 的调用情况。
通过 -T 选项显示每一调用所耗的时间,使用 -e 选项单独跟踪系统调用。

1
strace -p 202 -Te write

strace-3

最右侧可以看到 write 每次调用所消耗的时间。知道这些,我们可以进一步分析定位程序产生问题的具体位置。

我们还可以用过滤 write 操作的调用

1
strace -Tf -p 202 2>&1 | grep -v write

strace-4

如果需要同时跟踪多个 PID 呢?

1
strace -f $(pidof php-fpm | sed 's/\([0-9]*\)/\-p \1/g')

一些有用的选项
-c 统计每一系统调用的所执行的时间,次数和出错的次数等
-f 跟踪由fork调用所产生的子进程
-t 在输出中的每一行前加上时间信息
-T 显示每一调用所耗的时间
-e trace=open,close 只跟踪系统 openclose 调用

strace 是内核态的调用跟踪,如果是用户态的调用,这时得用 ltrace 了。

相关链接

(完)