千家信息网

使用strace工具故障排查的5种简单方法

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,strace 是一个非常简单的工具,用来跟踪可执行程序的系统调用(system call)。最简单的使用是,它追踪可行程序运行时的整个生命周期,输出每一个系统调用的名字,参数和返回值。但是它还可以做更
千家信息网最后更新 2026年11月02日使用strace工具故障排查的5种简单方法

strace 是一个非常简单的工具,用来跟踪可执行程序的系统调用(system call)。最简单的使用是,它追踪可行程序运行时的整个生命周期,输出每一个系统调用的名字,参数和返回值。

但是它还可以做更多的事情:

它可以基于系统调用或者系统调用组来过滤

它可以通过计算制定系统调用的次数,花费的时间以及成功和失败的次数来描述系统调用的使用

它可以追踪发送给进程的信号(signal)

它可以通过进程id(pid)号加入到任意正在运行的进程上

如何使用

这里只是简单的描述strace如何使用,并不打算对此做深入分析

找出一个程序启动时读取了哪个配置文件

有的时候,你发发现,无论你如何修改配置文件,应用程序并没有按照你的思路去运行,这是什么原因?一个浅显但容易忽视的考虑是,应用程序启动时读取了你认为要读取的配置文件了吗?看下面的例子:

$ strace php 2>&1 | grep php.ini open("/usr/local/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/local/lib/php.ini", O_RDONLY) = 4 lstat64("/usr/local/lib/php.ini", {st_mode=S_IFLNK|0777, st_size=27, ...}) = 0 readlink("/usr/local/lib/php.ini", "/usr/local/Zend/etc/php.ini", 4096) = 27 lstat64("/usr/local/Zend/etc/php.ini", {st_mode=S_IFREG|0664,st_size=40971, ...}) = 0

上述php程序程序会首先从/usr/local/bin/下读取php.ini文件,也许不是你想的首先从/usr/local/lib/下读取。

上述的输出会很多,我们甚至可以通过参数来指定只追踪我们关心的系统调用,类似如下:

$ strace -e open php 2>&1 | grep php.ini open("/usr/local/bin/php.ini", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/local/lib/php.ini", O_RDONLY) = 4

为什么程序没有打开我的文件?

每一个可执行程序读取文件时,如果权限不够,则会遭拒绝。而如果文件找不到,也并不会报错,除非你在程序里设置了错误处理,So,如果程序没有读取我的文件,我该如何跟踪呢?

$ strace -e open,access 2>&1 |grep your-filename

检查open()和access()系统调用的输出结果,看看是什么原因

进程此刻正在做什么?

你的程序突然消耗了大量的CPU,或者程序似乎被挂起了,那么我们通过进程的pid号看看此刻它正在做什么

root@dev:~# strace -p 15427 Process 15427 attached - interrupt to quit futex(0x402f4900, FUTEX_WAIT, 2, NULL Process 15427 detached

通过跟踪,你知道程序挂起的原因是正在调用futex()。

程序的时间花在什么地方

你总是希望程序能够按照你的意愿去工作,也希望它能在正确的时间做正确的事情,甚至希望它是最优的,尽可能在程序运行的周期内,消耗的90%以上的资源都是在做需要做的事情,而不是简单的等待。也许,下面的这个指令可以帮上你的忙:

root@dev:~# strace -c -p 11084

Process 11084 attached - interrupt to quit

Process 11084 detached

% time seconds usecs/call calls errors syscall


94.59 0.001014 48 21 select

2.89 0.000031 1 21 getppid

2.52 0.000027 1 21 time


100.00 0.001072 63 total

root@dev:~#

如果你是跟踪的后台守护进程,可以通过上面的指令跟踪一段时间,然后按ctrl+c退出,strace会根据获得信息描述出上面的结果。

上述的例子说明当前进程(postmaster)最要的时间花在等待select()函数上,在每调用一次select函数后,它分别调用getpid函数和time函数. 如果是非后台守护进程,那strace可以跟踪进程的开始至结束,类似下面这样:

root@dev:~# strace -c >/dev/null ls

% time seconds usecs/call calls errors syscall


23.62 0.000205 103 2 getdents64

18.78 0.000163 15 11 1 open

15.09 0.000131 19 7 read

12.79 0.000111 7 16 old_mmap

7.03 0.000061 6 11 close

4.84 0.000042 11 4 munmap

4.84 0.000042 11 4 mmap2

4.03 0.000035 6 6 6 access

3.80 0.000033 3 11 fstat64

1.38 0.000012 3 4 brk

0.92 0.000008 3 3 3 ioctl

0.69 0.000006 6 1 uname

0.58 0.000005 5 1 set_thread_area

0.35 0.000003 3 1 write

0.35 0.000003 3 1 rt_sigaction

0.35 0.000003 3 1 fcntl64

0.23 0.000002 2 1 getrlimit

0.23 0.000002 2 1 set_tid_address

0.12 0.000001 1 1 rt_sigprocmask


100.00 0.000868 87 10 total

ls程序大部分时间花在读取目录条目上面。

为什么我不能连接到服务器?

调试进程不能连接到服务器是一个痛苦的事情,因为原因很多,比如DNS失效啦,连接被挂起啦,服务器返回异常数据啦,服务器本身异常啦,等等。一般网络调试方面,很多人会想到另外一个非常不错的工具-tcpdump。但它的参数太多了,而且你要从上百个连接进程中找出其中一个进程为什么不能连接恐怕是一件非常费力的工作。strace 其实也能在这种情景下帮上你的忙,它仅仅输出与系统调用相关的数据,从而可以让我们的注意力更集中。类似下面这样:

$ strace -e poll,select,connect,recvfrom,sendto nc http://www.news.com 80

sendto(3, "\24\0\0\0\26\0\1\3\255\373NH\0\0\0\0\0\0\0\0", 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20

connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)

connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)

connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0

poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1

sendto(3, "\213\321\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\34\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30

poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1

recvfrom(3, "\213\321\201\200\0\1\0\1\0\1\0\0\3www\4news\3com\0\0\34\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 153

connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0

poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1

sendto(3, "k\374\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\1\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30

poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1

recvfrom(3, "k\374\201\200\0\1\0\2\0\0\0\0\3www\4news\3com\0\0\1\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 106

connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, 28) = 0

poll([{fd=3, events=POLLOUT, revents=POLLOUT}], 1, 0) = 1

sendto(3, "\\2\1\0\0\1\0\0\0\0\0\0\3www\4news\3com\0\0\1\0\1", 30, MSG_NOSIGNAL, NULL, 0) = 30

poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 5000) = 1

recvfrom(3, "\\2\201\200\0\1\0\2\0\0\0\0\3www\4news\3com\0\0\1\0\1\300\f"..., 1024, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("62.30.112.39")}, [16]) = 106

connect(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("216.239.122.102")}, 16) = -1 EINPROGRESS (Operation now in progress)

select(4, NULL, [3], NULL, NULL) = 1 (out [3])

那么,上述的输出,说明进程发生了什么呢?

注意到这个进程尝试连接/var/run/nscd/socket连接了吗?这意味着nc程序首先会去连接NSCD- Name Service Cache Daemon - 它通常用于设置和NIS,YP,LDAP或者类似目录协议相关的域名查询配置上。在上述例子中,连接失败了。

接下来进程开始连接到DNS,这点可以从sin_port=htons(53)输出可以看出。你可以看到,它接着做了一个sendto()的调用,发出了一个包含http://www.news.com信息的DNS包。然后读取返回的包数据,不知什么原因,它做了三次这样的尝试。一个可能的原因是http://www.news.com是一条CNAME记录。多次请求可能是nc程序处理的一种方式。

最后,它总算是发起了connect()操作,注意这个操作的返回结果是EINPROGRESS,这意味着这个连接是非阻塞式的,nc希望继续,于是它调用了select()。

增加read,write调用到strace跟踪的系统调用列表里,可以让我们看到下面的一些结果:

read(0, "test\n", 1024) = 5

write(3, "test\n", 5) = 5

poll([{fd=3, events=POLLIN, revents=POLLIN}, {fd=0, events=POLLIN}], 2, -1) = 1

read(3, "

上述表示它从读取"test" + 标准输入的一行信息,然后写入网络连接,接着调用poll来等待回应,然后读取网络反馈的信息并写到标准输出。

程序 进程 系统 文件 跟踪 输出 原因 时间 面的 事情 信息 函数 可以通过 服务器 正在 结果 服务 运行 配置 例子 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网与科技 博彦科技互联网金融 A股互联网金融科技公司 科技互联网项目 互联网品科技 互联网金融 科技 金融科技和互联网金融 互联网科技类展会 广西拼得多互联网科技有限公司 成都玖崟互联网科技有限公司乐商圈怎么样 中盈科技互联网信息有限公司 欧洲十大科技互联网公司 浙南科技城互联网大厦建设工程 中天科技中国工业互联网 2021世界互联网领先科技成果发布 新氧科技和美国互联网有关系吗 西安左小互联网科技有限公司 互联网科技的前景 绵阳真晨互联网科技有限公司 盐城市攀科互联网科技有限公司 互联网科技活动banner 中国 科技 互联网 万易互联网科技 互联网科技公司有哪些 互联网行业科技股 保险科技服务互联网营销体系 国大互联网教育科技有限公司薪资 互联网领先科技宣传片 互联网时代高科技布局 互联网高科技绘画
0