如何使用strace来解决问题?

如题,虽然可能很多地方都有类似介绍。

程序的配置文件在哪?

老生长叹,毕竟你不知道这个程序的配置文件是在用户根目录,还是systemd内。

因为一个程序有一百万种方法来记录它的配置文件在哪里(在手册页、网站上、–help等),但只有一种方法可以让它真正打开它(用系统调用!)。

比如我现在找一下apt的配置文件。

1
2
3
4
5
6
7
8
9
10
11
# strace -tf apt 2>&1|grep stat
.....
17:07:05 stat("/etc/apt/apt.conf.d/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
17:07:05 stat("/etc/apt/apt.conf.d/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
17:07:05 fstat(4, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
17:07:05 stat("/etc/apt/apt.conf", 0x7ffe7ec576b0) = -1 ENOENT (No such file or directory)
17:07:05 stat("/var/lib/dpkg/status", {st_mode=S_IFREG|0644, st_size=576398, ...}) = 0
17:07:05 stat("/usr/bin/dpkg", {st_mode=S_IFREG|0755, st_size=313888, ...}) = 0
17:07:05 stat("/etc/debian_version", {st_mode=S_IFREG|0644, st_size=13, ...}) = 0
17:07:05 stat("/usr/share/dpkg/tupletable", {st_mode=S_IFREG|0644, st_size=2249, ...}) = 0
17:07:05 fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0

很明显可以看到apt.conf.d被加入了加载列表,以及apt.conf

为什么会挂掉?

执行程序,却什么输出都没有,这是怎么回事?

很多时候你只需要运行strace -p PID,看看当前运行的是什么系统调用。你甚至不需要看几百行的输出。

如果这个程序闪没了咋办?

试试这个!strace <command>

为什么很慢?

使用 strace 作为一种粗略的剖析工具strace -t <command>

会显示每次系统调用的时间戳,这样你就可以寻找大的漏洞,找到罪魁祸首。

或者用统计工具 strace -c <command>

为什么这个网络连接失败?

你可以通过DNS请求来查找域名,或者通过connect系统调用来查找IP。

一般来说,当tcpdump因为某些原因不能使用或者只是因为比较熟悉strace时,就经常会使用strace调试网络问题。

比如服务器curl ifconfig.me一直不出结果。
这时候strace curl ifconfig.me检查了一下。

1
2
3
4
5
6
7
8
9
10
11
12
sendto(3, "GET HTTP://ifconfig.me/ HTTP/1.1"..., 172, MSG_NOSIGNAL, NULL, 0) = 172
poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=3, events=POLLIN}], 1, 1000) = 0 (Timeout)
poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=3, events=POLLIN}], 1, 1000) = 0 (Timeout)
poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=3, events=POLLIN}], 1, 1000) = 0 (Timeout)
poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=3, events=POLLIN}], 1, 1000) = 0 (Timeout)
poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)
poll([{fd=3, events=POLLIN}], 1, 1000) = 0 (Timeout)
poll([{fd=3, events=POLLIN|POLLPRI|POLLRDNORM|POLLRDBAND}], 1, 0) = 0 (Timeout)

发现一直超时,这样头绪会清晰一些,至少不是机器有问题。