目录
一、strace 是什么?
strace
是 Linux 系统中用于跟踪进程系统调用(System Call)和信号(Signal)的工具。
核心功能:
- 监控进程执行时发生的系统调用,显示每个调用的参数和返回值。
- 跟踪进程收到的信号及其处理方式。
- 诊断程序运行时的异常(如文件打开失败、权限问题、网络连接错误等)。
- 分析程序性能瓶颈,定位系统资源消耗点。
二、基本语法与选项
strace [选项] [命令及参数]
# 示例:跟踪 ls 命令的系统调用
strace ls /etc
常用选项:
选项 | 说明 |
---|---|
-c | 统计每个系统调用的执行次数、耗时及资源占用(CPU 时间),输出汇总报告。 |
-d | 输出调试信息到标准错误(stderr),用于排查 strace 自身问题。 |
-f | 跟踪子进程(如通过 fork() 或 vfork() 产生的进程)。 |
-F | 与 -f 类似,但支持跟踪多线程程序(通过 clone() 创建的线程)。 |
-o <文件> | 将输出重定向到指定文件,避免屏幕输出过多内容。 |
-p <PID> | 附加到已运行的进程(需 root 权限或目标进程属主权限)。 |
-s <长度> | 设置输出的字符串截断长度(默认 32 字节),避免长字符串被截断。 |
-T | 在每行输出后显示系统调用的耗时(单位:秒)。 |
-v | 详细显示系统调用的参数(默认会简化部分参数)。 |
-x | 以十六进制格式显示非字符串参数。 |
-XX | 以十六进制格式显示所有参数(包括字符串)。 |
-e <表达式> | 过滤系统调用或信号,格式为 [!]类型=值 (如 -e trace=open 仅跟踪 open 调用)。 |
-E <变量=值> | 为被跟踪进程设置环境变量(如 -E LD_LIBRARY_PATH=/path )。 |
三、系统调用与信号的跟踪逻辑
-
系统调用(System Call)
- 是用户空间程序向内核请求服务的接口(如
read()
、write()
、open()
等)。 strace
输出格式:系统调用名(参数1, 参数2, ...) = 返回值 # 示例:open("/etc/passwd", O_RDONLY) = 3
- 返回值为
-1
时表示调用失败,errno
可通过strerror(errno)
转换为错误信息。
- 是用户空间程序向内核请求服务的接口(如
-
信号(Signal)
- 如
SIGINT
(Ctrl+C)、SIGSEGV
(段错误)等。 strace
输出格式:<信号名> 或 <信号编号> (处理方式:默认/忽略/捕获) # 示例:--- SIGCHLD (Child exited) ---
- 如
四、典型使用场景与示例
场景 1:诊断程序启动失败
问题:程序 test.sh
启动后无输出且退出,排查原因。
strace -o strace.log ./test.sh
# 分析日志,查找是否有权限错误(如 EACCES)或文件不存在(ENOENT)
grep -i "error\|no such file" strace.log
场景 2:跟踪子进程
需求:跟踪 ls
命令及其子进程(如 ls
调用 fork
生成的进程)。
strace -f ls /usr/bin
场景 3:统计系统调用耗时
需求:分析 curl
访问网页时的性能瓶颈。
strace -c curl https://example.com
# 输出结果中查看各系统调用的耗时占比,定位耗时最长的调用(如 `connect`、`read` 等)
场景 4:附加到正在运行的进程
需求:跟踪 PID 为 1234 的进程当前行为。
strace -p 1234
# 按 Ctrl+C 停止跟踪
场景 5:过滤特定系统调用
需求:仅跟踪 open
和 read
调用。
strace -e trace=open,read ls /etc
场景 6:调试多线程程序
需求:跟踪多线程程序的线程间交互。
strace -F -o thread.log ./multithread_app
五、输出结果解析
以下是 strace ls /etc
的部分输出示例:
execve("/usr/bin/ls", ["ls", "/etc"], 0x7ffd6b4d5a6c0 /* 25 vars */) = 0
brk(NULL) = 0x55c4c8d26000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=119732, ...}) = 0
mmap(NULL, 119732, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f9e90a9d000
close(3) = 0
...
关键字段解析:
execve
:进程启动时执行的第一个系统调用,加载程序二进制文件。brk
:调整堆(Heap)内存大小。access
:检查文件权限。openat
:打开文件(AT_FDCWD
表示当前工作目录)。mmap
:将文件映射到内存(如动态链接库)。close
:关闭文件描述符。
六、注意事项
-
权限问题:
- 跟踪非当前用户的进程或某些敏感系统调用(如
ptrace
)需root
权限。 - 部分系统可能限制普通用户使用
strace
(需配置/etc/sysctl.d/10-ptrace.conf
)。
- 跟踪非当前用户的进程或某些敏感系统调用(如
-
性能影响:
strace
会增加被跟踪进程的运行开销,不建议在生产环境长时间跟踪高负载进程。
-
输出过滤:
- 系统调用数量庞大时,建议结合
-e trace
或grep
过滤关键信息,避免日志爆炸。
- 系统调用数量庞大时,建议结合
-
多线程与子进程:
- 跟踪多线程程序需使用
-F
,跟踪子进程需使用-f
或-fork
。
- 跟踪多线程程序需使用
七、扩展:类似工具对比
工具 | 用途 | 特点 |
---|---|---|
strace | 跟踪系统调用和信号 | 适用于用户空间程序,功能全面 |
ltrace | 跟踪库函数调用 | 聚焦 C 库函数(如 printf 、malloc ) |
perf | 性能分析 | 基于事件采样,适合内核级性能调优 |
gdb | 调试器 | 支持断点、变量查看,适合程序调试 |
八、总结
strace
是 Linux 下诊断程序问题的核心工具之一,尤其在排查文件 I/O、网络请求、权限问题时非常有效。通过掌握其常用选项和输出解析方法,可快速定位程序运行时的异常点,提升调试效率。