strace 速查表
此文是 strace cheat sheet 的翻译。
TL;DR
strace
可以追踪系统调用、信号,在调试中,它还是收集上下文环境的非常好的工具。 此速查表将会展示一些技巧来说明 strace
的使用方法、如何过滤输出,并且介绍了一些 strace
的实用参数。
strace PTRACE_TRACEME EPERM (Operation not permitted)
你应该以 root 身份来运行 strace
。如果你以 root 用户运行,也得到这个提示,这说明在你的系统中,strace
不允许附加到进程上。 你可以修改 /proc
中的设置,来开启 strace
附加到进程的功能:
1 | sudo bash -c 'echo 0 > /proc/sys/kernel/yama/ptrace_scope' |
为了让这个修改永久生效,请首先检查你的系统有没有 /etc/sysctl.d/10-ptrace.conf
文件。 如果你的系统有这个文件,修改该文件:
1 | kernel.yama.ptrace_scope = 0 |
如果你的系统没有这个文件:
- 打开
/etc/sysctl.conf
文件 - 找到设置
kernel.yama.ptrace_scope
- 如果该设置存在,将其修改为 0
- 如果不存在,添加一行
kernel.yama.ptrace_scope = 0
strace pid
strace 一个运行中的进程
1 | strace -p [pid] |
strace 一个运行中的进程和线程
1 | strace -fp [pid] |
strace 一个运行中的进程并且输出字符串
1 | strace -s 80 -fp [pid] |
此命令会输出每一个字符串的前 80 个字符。
strace 一个程序
strace 一个程序
1 | strace ./program |
strace 一个程序和线程
1 | strace -f ./program |
strace 一个程序并且输出字符串
1 | strace -s 80 -f ./program |
此命令会输出每一个字符串的前 80 个字符。
strace futex
使用 strace
的时候,经常会看到很多 futex
系统调用,比如:
1 | [pid 2082] futex(0x7f4c4d3bff30, FUTEX_WAKE_PRIVATE, 1) = 0 <0.000003> |
futex
系统调用被很多线程库广泛使用,比如 libpthread ,用来实现更高层次的锁原语,比如 mutexes(互斥器)、semaphore(信号量)等。
过滤掉 futex 调用
如果你的程序使用了大量的 futex 调用,而且你也不希望看到它们,你可以: 使用 grep
过滤掉 futex
调用:
1 | strace strace -Tf ./program 2>&1 | grep -v futex |
或者,追踪一些你真正关注的系统调用。比如,追踪此程序和其线程调用的 open、read和write调用:
1 | strace -Tfe trace=open,read,write ./program |
其他有用的选项
strace 有很多实用的选项。一些常用的选项如下:
-f
追踪创建的线程和子进程。许多程序会派生出额外的进程或者线程来完成一些工作,所以此选项很有用。-T
输出系统调用花费的时间。当你需要确认特定的系统调用是否花费了很多时间的时候,此选项会有帮助。-t
在每行输出当前时间(没有日期)。-s [size]
每个字符串输出 size 个字符。如果程序在写入文件描述符,此选项会有帮助。-c
输出系统调用次数、系统调用花费的时间的直方图。-e trace=open,close
仅仅追踪 open 和 close 系统调用。
如果需要查看全部的命令行参数,请查看 strace
的文档。
总结
在 Linux 上调试的时候, strace
是必不可少的工具。当你需要了解一个程序在做什么的时候,你应该使用 strace
。作为防御式调试的第一条命令,strace
是收集程序上下文信息的不错的方法。
strace
接收许多命令行参数,读者最好阅读 strace
文档来了解全部参数。