跳转至

strace 系统调用跟踪

strace 是 Linux 的系统调用追踪工具,可以看到程序在底层到底调用了哪些操作系统功能。白话说就是"给程序装个监控摄像头,看它在后台偷偷做了什么"。

核心知识点

概念说明
系统调用(syscall)程序请求操作系统干活(打开文件、读写、网络等)
strace追踪程序的系统调用和信号
open/openat打开文件的系统调用
read/write读写数据的系统调用
connect/socket网络连接的系统调用
execve执行新程序的系统调用
信号(signal)进程间通信的机制(如 SIGKILL、SIGTERM)

安装配置

# Ubuntu/Debian 安装
sudo apt install strace  # 安装 strace

# CentOS/RHEL 安装
sudo yum install strace  # 安装 strace

# 确认安装
strace --version  # 查看版本

基本使用

追踪命令

# 追踪一个命令的所有系统调用
strace ls /tmp  # 看 ls 命令在底层做了什么
# 输出会显示每个系统调用、参数和返回值

# 追踪并只显示特定类型的系统调用
strace -e open ls /tmp  # 只看打开文件的调用
strace -e read,write ls /tmp  # 只看读写操作
strace -e network ls /tmp  # 只看网络相关的调用

# 追踪子进程(程序启动的其他进程也一起追踪)
strace -f bash -c "echo hello"  # -f 跟踪子进程

# 显示调用耗时
strace -T ls /tmp  # -T 在每行后面显示这个调用花了多长时间

# 显示时间戳
strace -t ls /tmp   # 显示时间(秒)
strace -tt ls /tmp  # 显示时间(微秒)
strace -ttt ls /tmp # 显示 Unix 时间戳

追踪正在运行的进程

# 追踪正在运行的进程(需要 root 或相同用户)
sudo strace -p 12345  # 12345 是进程 PID

# 先找到进程 PID
pidof nginx  # 查看 nginx 的 PID
pgrep -f "python app.py"  # 查找 python 进程的 PID

# 追踪并且不中断进程
sudo strace -p $(pidof nginx) -e read,write  # 只看 nginx 的读写操作

# 追踪多线程程序
sudo strace -fp $(pidof nginx)  # -f 同时追踪所有线程

高级用法

按类型过滤系统调用

# 只看文件相关操作
strace -e trace=file ls  # 所有文件相关:open、stat、unlink 等

# 只看网络相关操作
strace -e trace=network curl example.com  # socket、connect、send 等

# 只看进程管理
strace -e trace=process bash -c "ls"  # fork、exec、wait 等

# 只看内存操作
strace -e trace=memory ls  # mmap、brk 等

# 只看信号
strace -e trace=signal ls  # 信号相关

# 组合多种类型
strace -e trace=file,network curl example.com  # 文件 + 网络

统计分析

# 统计系统调用次数和耗时(非常实用)
strace -c ls /tmp  # -c 显示统计摘要
# 输出类似:
# % time  seconds  calls  errors  syscall
# 25.00   0.001     10      2     openat
# 15.00   0.000     20      0     read
# ...

# 统计 + 详细输出
strace -C ls /tmp  # -C 既显示详细又显示统计

# 排序统计结果
strace -c -S time ls /tmp  # 按时间排序
strace -c -S calls ls /tmp  # 按调用次数排序

输出到文件

# 输出到文件(不影响终端)
strace -o trace.log ls /tmp  # -o 输出到文件

# 追踪多进程时每个进程一个文件
strace -ff -o trace.log bash -c "ls; date"
# 会生成 trace.log.PID1, trace.log.PID2...

# 追加模式
strace -o trace.log -p 12345  # 追踪运行中的进程并保存

实用排查场景

# 场景1:程序找不到文件
strace -e openat python app.py 2>&1 | grep "No such file"
# 看程序在哪些路径下找文件,找不到的会显示 ENOENT

# 场景2:程序启动慢,找出瓶颈
strace -c -S time python app.py  # 统计哪个调用最耗时

# 场景3:程序连不上数据库
strace -e connect python app.py 2>&1 | grep -i "connect"
# 看连接的 IP 和端口对不对

# 场景4:查看程序读了哪些配置文件
strace -e openat nginx -t 2>&1 | grep ".conf"
# 看 nginx 测试时读了哪些配置文件

# 场景5:程序卡住了(hang),看在等什么
sudo strace -p $(pidof myapp)  # 看它卡在哪个系统调用上
# 如果卡在 read/poll/select,说明在等待 IO
# 如果卡在 futex,说明在等锁

# 场景6:看程序的环境变量
strace -e trace=read -s 1000 env 2>&1 | head -20
# -s 1000 显示更长的字符串

过滤文件描述符

# 只看特定文件描述符的读写
strace -e read=3 -e write=3 ls  # 只看文件描述符 3 的读写

# 显示完整的字符串内容(默认截断 32 字符)
strace -s 500 cat /etc/hosts  # -s 500 显示前 500 个字符
strace -s 0 cat /etc/hosts    # -s 0 不限长度,显示全部

常见报错

问题原因解决
attach: Operation not permitted没有权限追踪其他用户的进程sudo 或修改 ptrace_scope
输出太多看不过来没有过滤-e trace=file 等过滤
字符串被截断默认只显示 32 字符-s 500-s 0
追踪导致程序变慢strace 有性能开销-c 统计模式减少开销
No such processPID 不存在或已退出ps 确认进程还在

速查表

# === 基础追踪 ===
strace 命令                    # 追踪命令
strace -p PID                  # 追踪运行中的进程
strace -f 命令                 # 连子进程一起追踪
strace -o 文件 命令            # 输出到文件

# === 过滤 ===
strace -e trace=file 命令      # 只看文件操作
strace -e trace=network 命令   # 只看网络操作
strace -e trace=process 命令   # 只看进程操作
strace -e openat,read 命令     # 只看特定调用

# === 显示控制 ===
strace -s 500 命令             # 字符串显示 500 字符
strace -T 命令                 # 显示每个调用耗时
strace -t/-tt 命令             # 显示时间戳

# === 统计 ===
strace -c 命令                 # 统计摘要
strace -C 命令                 # 详细 + 统计
strace -c -S time 命令         # 按耗时排序

# === 常见组合 ===
strace -e openat 命令 2>&1 | grep "No such file"   # 找缺失文件
strace -e connect 命令 2>&1 | grep connect          # 看网络连接
strace -c -S time 命令                              # 性能瓶颈分析
sudo strace -p PID -e trace=file                    # 看进程文件操作