Skip to main content

strace 完全使用指南

·6 mins

strace 完全使用指南 #

目录 #

  1. strace 简介
  2. 基础语法
  3. 核心参数详解
  4. 过滤和跟踪选项
  5. 输出格式控制
  6. 性能分析参数
  7. 实用场景示例
  8. 输出解读指南
  9. 性能调优技巧
  10. 最佳实践

1. strace 简介 #

1.1 什么是 strace #

strace 是 Linux 系统下的系统调用跟踪工具,它可以:

  • 监控进程执行的所有系统调用
  • 显示系统调用的参数和返回值
  • 统计系统调用的执行时间和频率
  • 跟踪信号传递过程
  • 分析程序的系统级行为

1.2 主要用途 #

性能分析     → 找出系统调用瓶颈
故障排查     → 定位程序异常原因
安全审计     → 监控程序系统访问
逆向分析     → 理解程序运行机制
系统调优     → 优化系统调用使用

2. 基础语法 #

2.1 命令格式 #

# 基础语法
strace [选项] [命令]
strace [选项] -p <进程ID>

# 示例
strace ls /tmp                    # 跟踪 ls 命令
strace -p 1234                    # 跟踪进程ID为1234的进程
strace -e trace=network curl baidu.com  # 只跟踪网络相关系统调用

2.2 两种使用模式 #

模式1:启动新进程并跟踪

strace ./my_program
strace -o trace.log ./my_program

模式2:附加到已运行的进程

strace -p $(pgrep program_name)
strace -p 1234

3. 核心参数详解 #

3.1 进程相关参数 #

参数含义示例
-p <pid>附加到指定进程IDstrace -p 1234
-f跟踪子进程strace -f ./parent_program
-F(已废弃)跟踪vfork创建的子进程,现代strace中 -f 已涵盖fork/vfork/clone,-F 等同于 -fstrace -f ./program
-ff为每个进程创建单独的输出文件strace -ff -o trace ./program

使用示例:

# 跟踪多进程程序
strace -f -o multi_process.trace ./nginx

# 为每个进程单独输出
strace -ff -o trace_ ./multi_thread_app
# 生成: trace_1234, trace_1235, trace_1236...

3.2 输出控制参数 #

参数含义示例
-o <file>输出到文件strace -o output.log ./program
-s <size>字符串显示长度strace -s 1024 ./program
-v详细模式strace -v ./program
-x十六进制显示非ASCII字符strace -x ./program
-xx所有字符串都用十六进制strace -xx ./program

字符串显示对比:

# 默认显示 (截断)
read(3, "Hello World"..., 1024) = 11

# 增加显示长度
strace -s 1024 ./program
read(3, "Hello World! This is a long string...", 1024) = 38

# 十六进制显示
strace -x ./program
read(3, "Hello\x20World\x21", 12) = 12

4. 过滤和跟踪选项 #

4.1 系统调用过滤 #

4.1.1 基本过滤语法 #

# 只跟踪指定的系统调用
strace -e trace=<syscall_set> ./program

# 排除指定的系统调用
strace -e trace=!<syscall_set> ./program

4.1.2 系统调用分类 #

分类含义包含的系统调用
file文件操作open, read, write, close, stat
process进程管理fork, exec, exit, wait
network网络操作socket, bind, listen, accept, send, recv
signal信号处理kill, signal, sigaction
ipc进程间通信pipe, msgget, semget, shmget
desc文件描述符select, poll, epoll
memory内存管理mmap, munmap, brk, mprotect

使用示例:

# 只跟踪网络相关系统调用
strace -e trace=network ./network_app

# 跟踪文件和网络操作
strace -e trace=file,network ./web_server

# 排除内存管理相关调用
strace -e trace=!memory ./program

# 跟踪特定的系统调用
strace -e trace=read,write,open,close ./file_processor

4.2 高级过滤选项 #

4.2.1 错误过滤 #

# 只显示失败的系统调用
strace -e trace=all -e fault=eperm ./program

# 只显示返回错误的调用
strace -Z ./program

# 跟踪特定错误码
strace -e trace=all -e abbrev=none -e verbose=all ./program

4.2.2 文件描述符过滤 #

# 只跟踪特定文件描述符的操作
strace -e write=1,2 ./program        # 只跟踪stdout和stderr
strace -e read=0 ./program           # 只跟踪stdin读取

5. 输出格式控制 #

5.1 时间相关参数 #

参数含义输出格式
-t显示时间戳HH:MM:SS
-tt显示微秒级时间戳HH:MM:SS.microseconds
-ttt显示Unix时间戳seconds.microseconds
-T显示系统调用耗时<0.000123>
-r显示相对时间自上次系统调用的时间间隔

时间输出示例:

# 标准时间戳
strace -t ./program
14:30:25 open("/etc/passwd", O_RDONLY) = 3

# 微秒级精度
strace -tt ./program
14:30:25.123456 open("/etc/passwd", O_RDONLY) = 3

# 显示执行时间
strace -T ./program
open("/etc/passwd", O_RDONLY) = 3 <0.000089>

# 相对时间
strace -r ./program
     0.000000 open("/etc/passwd", O_RDONLY) = 3
     0.000234 read(3, "root❌0:0:root:/root:/bin/bash\n", 4096) = 32

5.2 输出详细程度 #

# 详细模式 - 显示完整的结构体内容
strace -v ./program

# 简化模式 - 省略常见结构体的详细信息
strace -e abbrev=all ./program

# 自定义省略
strace -e abbrev=read,write ./program

对比示例:

# 默认输出
stat("/tmp", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0

# 详细输出
strace -v ./program
stat("/tmp", {st_dev=makedev(0, 24), st_ino=2, st_mode=S_IFDIR|0755, 
    st_nlink=18, st_uid=0, st_gid=0, st_rdev=makedev(0, 0), 
    st_size=4096, st_blksize=4096, st_blocks=8, ...}) = 0

6. 性能分析参数 #

6.1 统计分析 #

# 生成系统调用统计报告
strace -c ./program

# 按时间排序
strace -c -S time ./program

# 按调用次数排序  
strace -c -S calls ./program

# 按调用名称排序
strace -c -S name ./program

统计输出示例:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 99.98    0.017711       17711         1           restart_syscall
  0.02    0.000004           4         1           futex
------ ----------- ----------- --------- --------- ----------------
100.00    0.017715        8857         2           total

6.2 性能监控参数 #

参数含义用途
-c统计模式生成调用次数和时间统计
-C统计+详细模式同时输出详细调用跟踪和汇总统计信息
-S <sort>排序方式time/calls/name/nothing
-w总结挂起的系统调用显示被阻塞的调用

7. 实用场景示例 #

7.1 网络程序分析 #

# 分析网络程序的系统调用
strace -e trace=network -tt -T -o network.log ./web_server

# 只关注socket操作
strace -e trace=socket,bind,listen,accept,send,recv ./network_app

# 分析连接建立过程
strace -e trace=network -v ./client_program

7.2 文件I/O分析 #

# 跟踪文件操作
strace -e trace=file -s 256 ./file_processor

# 查看配置文件读取
strace -e trace=openat,read -e file ./config_reader

# 分析写入性能
strace -e trace=write -T ./data_writer

7.3 性能瓶颈定位 #

# 找出最耗时的系统调用
strace -c -S time ./slow_program

# 分析高频系统调用
strace -c -S calls ./busy_program

# 监控长时间运行的进程
strace -p $(pgrep long_running) -c -T

7.4 多进程程序调试 #

# 跟踪父子进程
strace -f -o family.log ./parent_process

# 为每个进程单独输出
strace -ff -o trace_ ./multi_process_app

# 跟踪线程创建
strace -f -e trace=clone ./threaded_app

7.5 SSL/TLS程序分析 #

基于我们前面的实际案例:

# 分析HTTPS连接过程
strace -e trace=network,file -s 1024 ./https_client

# 查看证书读取过程
strace -e trace=openat,read -e file=/etc/ssl ./ssl_app

# 分析TLS握手
strace -e trace=sendto,recvfrom -x ./tls_client

8. 输出解读指南 #

8.1 系统调用格式 #

系统调用名(参数1, 参数2, ...) = 返回值 <执行时间>

示例解析:

# 文件打开
openat(AT_FDCWD, "/etc/passwd", O_RDONLY) = 3
#  ↑           ↑                    ↑        ↑
# 调用名    工作目录             文件路径    返回的文件描述符

# 网络发送
sendto(16, "\26\3\1\2\0\1\0\1\374...", 517, MSG_NOSIGNAL, NULL, 0) = 517
#  ↑   ↑              ↑                ↑         ↑         ↑    ↑     ↑
# 调用名 fd          数据内容         长度      标志      地址  长度  返回值

# 轮询等待
poll([{fd=16, events=POLLIN}], 1, 167) = 1 ([{fd=16, revents=POLLIN}])
#  ↑        ↑         ↑          ↑   ↑     ↑            ↑
# 调用名  文件描述符  关注事件    数量 超时  返回数量    实际事件

8.2 常见返回值含义 #

返回值含义示例
> 0成功,返回字节数/描述符等read() = 1024
0成功,特殊含义read() = 0 (EOF)
-1失败open() = -1 ENOENT
?进程退出/信号中断read() = ? ERESTART

8.3 常见错误码 #

错误码含义常见原因
ENOENT文件不存在路径错误、文件被删除
EACCES权限不足文件权限、SELinux
EAGAIN资源暂时不可用非阻塞I/O、资源忙
EINPROGRESS操作正在进行非阻塞connect
EINTR被信号中断信号处理
EPIPE管道破裂对端关闭连接

9. 性能调优技巧 #

9.1 减少strace开销 #

# 只跟踪必要的系统调用
strace -e trace=network ./program

# 使用统计模式减少输出
strace -c ./program

# 限制字符串长度
strace -s 64 ./program

# 输出到文件而不是终端
strace -o output.log ./program

9.2 大量数据处理 #

# 使用压缩输出
strace -o >(gzip > trace.gz) ./program

# 分离错误输出
strace -o trace.out 2>trace.err ./program

# 实时监控关键调用
strace -e trace=network -f ./program | grep -E "(send|recv)"

9.3 长期监控 #

# 周期性统计
while true; do
    timeout 60 strace -c -p $(pgrep myapp) 2>&1 | \
        tee -a stats_$(date +%H%M).log
    sleep 300
done

# 监控特定条件
strace -e trace=all -p $(pgrep myapp) 2>&1 | \
    awk '/ENOENT/ {print strftime("%Y-%m-%d %H:%M:%S"), $0}'

10. 最佳实践 #

10.1 调试最佳实践 #

# 1. 从统计开始
strace -c ./program

# 2. 定位问题系统调用
strace -e trace=network -T ./program

# 3. 详细分析特定调用
strace -e trace=sendto,recvfrom -v -s 1024 ./program

# 4. 时间序列分析
strace -tt -T -o detailed.log ./program

10.2 性能分析最佳实践 #

# 对比分析
strace -c ./old_version > old_stats.txt
strace -c ./new_version > new_stats.txt
diff old_stats.txt new_stats.txt

# 瓶颈定位
strace -c -S time ./program | head -10

# 热点分析
strace -c -S calls ./program | head -10

10.3 生产环境使用注意事项 #

10.3.1 性能影响 #

# strace会显著影响程序性能,生产环境谨慎使用
# 建议:
# 1. 短时间跟踪
timeout 30 strace -p $PID

# 2. 只跟踪关键调用
strace -e trace=network -p $PID

# 3. 使用统计模式
strace -c -p $PID

10.3.2 安全考虑 #

# 避免敏感信息泄露
strace -e trace=network -s 0 ./program  # 不显示数据内容
strace -o /dev/null -c ./program        # 只要统计,不要详细日志

10.4 常用组合命令 #

# 网络程序完整分析
strace -f -e trace=network -tt -T -s 256 -o network_trace.log ./network_app

# 文件I/O性能分析
strace -e trace=file -c -S time ./file_app

# 多进程程序调试
strace -ff -o trace_ -e trace=process,network ./multi_process_app

# 实时监控生产程序
strace -p $(pgrep production_app) -e trace=network -c

总结 #

strace 是Linux系统调试和性能分析的强大工具,掌握其使用方法对于:

开发阶段 #

  • 理解程序系统调用行为
  • 优化I/O操作
  • 调试程序异常

运维阶段 #

  • 性能瓶颈定位
  • 故障原因分析
  • 系统行为监控

学习阶段 #

  • 理解操作系统原理
  • 学习系统编程
  • 分析程序运行机制

通过合理使用strace的各种参数和选项,可以深入了解程序的系统级行为,为性能优化和问题排查提供重要依据。

关键要点:

  • 选择合适的过滤条件减少噪音
  • 使用统计模式进行宏观分析
  • 结合时间信息定位性能瓶颈
  • 注意生产环境使用的性能影响
  • 善用组合参数提高分析效率