2. strace 安装与基础用法:在主流 Linux 发行版上安装 strace,运行第一个 strace 命令

strace 是 Linux 系统调用跟踪的行业标准工具,几乎所有主流发行版都将其收录在官方软件仓库中。本章将指导你完成安装并执行第一个跟踪命令,建立对 strace 输出格式的直观认识。

2.1 在主流发行版上安装 strace

strace 的安装方式因包管理器而异,下表汇总了最常见发行版的安装命令:

发行版 包管理器 安装命令
RHEL / CentOS / Rocky / AlmaLinux yum / dnf sudo yum install strace 或 sudo dnf install strace
Fedora dnf sudo dnf install strace
Debian / Ubuntu apt sudo apt update && sudo apt install strace
openSUSE zypper sudo zypper install strace
Arch Linux / Manjaro pacman sudo pacman -S strace
Alpine Linux apk sudo apk add strace
验证安装: 安装完成后,执行 strace --version 确认版本信息。输出应类似 strace -- version 5.19,表明工具已就绪。

2.2 运行第一个 strace 命令

最简单的用法是 strace <command>,它会跟踪指定命令执行期间发起的所有系统调用。以下示例跟踪 echo hello 命令:

$ strace echo hello
execve("/usr/bin/echo", ["echo", "hello"], 0x7ffc... /* 58 vars */) = 0
brk(NULL)                               = 0x55...
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f...
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=...}) = 0
mmap(NULL, ..., PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f...
close(3)                                = 0
...
write(1, "hello\n", 6)                  = 6
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

输出中每一行代表一次系统调用,格式为:调用名(参数...) = 返回值。例如 write(1, "hello\n", 6) = 6 表示向文件描述符 1(标准输出)写入 6 个字节,成功返回 6。

2.3 strace 输出结构解析

理解 strace 的输出格式是后续分析的基础。下图展示了典型输出的组成部分:

strace 输出行结构解析 write(1, "hello\n", 6) = 6 调用名 write 参数列表 (1, "hello\n", 6) 返回值 = 6 关键字段说明 • 调用名:系统调用的函数名称,如 openat、read、write、mmap • 参数列表:括号内为传入参数,文件描述符、缓冲区地址、长度等 • 返回值:等号后的数值,正数表示成功(如写入字节数),-1 表示失败 • 错误码:失败时显示 errno 名称和描述,如 ENOENT (No such file or directory)

2.4 常用命令行选项速查

strace 提供了丰富的选项来控制跟踪行为。以下是最常用的参数组合:

选项 功能说明 使用示例
-c 统计模式:汇总系统调用次数、耗时和错误数 strace -c ls
-p PID 附加到正在运行的进程,实时跟踪其系统调用 strace -p 1234
-e trace=open,read 只跟踪指定的系统调用(逗号分隔) strace -e trace=open,read ls
-o file 将输出写入文件,避免与目标进程输出混淆 strace -o trace.log ls
-t 在每行输出前添加时间戳(时:分:秒) strace -t ls
-T 显示每次系统调用的耗时(微秒级) strace -T ls
-f 跟踪子进程(fork 后同时跟踪子进程) strace -f nginx
-s 32 限制字符串参数显示长度(默认 32 字节) strace -s 128 ls
实战建议: 初次使用 strace 时,建议先以 strace -o /tmp/strace.log -t -T <command> 组合运行,既保留完整日志,又能看到每次调用的时间戳和耗时,便于快速定位慢调用。

2.5 第一个实战:跟踪 ls 命令

让我们用 strace 分析 ls 命令的行为,观察它如何获取目录内容:

$ strace -c ls /tmp
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 35.71    0.000025          25         1           getdents64
 28.57    0.000020          20         1           write
 14.29    0.000010          10         1           openat
 14.29    0.000010          10         1           close
  7.14    0.000005           5         1           fstat
------ ----------- ----------- --------- --------- ----------------
100.00    0.000070                     5           total

统计模式 -c 清晰展示了 ls 的核心工作流:

  • openat:打开目录文件描述符
  • getdents64:读取目录条目(耗时占比最高)
  • fstat:获取文件元信息
  • write:将结果输出到终端
  • close:关闭文件描述符
权限注意: 跟踪其他用户的进程或系统服务时,需要使用 sudo 提升权限。例如 sudo strace -p 1234。普通用户只能跟踪自己启动的进程。

2.6 常见安装问题与解决

以下是在安装或首次运行时可能遇到的典型问题及解决方案:

问题现象 可能原因 解决方法
strace: command not found 未安装 strace 或 PATH 未包含 使用对应包管理器安装;或执行 which strace 检查路径
strace: ptrace(PTRACE_TRACEME, ...): Operation not permitted 容器环境缺少 ptrace 权限 以 --privileged 模式启动容器,或添加 --cap-add=SYS_PTRACE
strace: attach: ptrace(PTRACE_SEIZE, PID): Operation not permitted 目标进程属于其他用户或受 YAMA LSM 保护 使用 sudo;或设置 echo 0 > /proc/sys/kernel/yama/ptrace_scope
输出大量 ... 省略行 默认字符串截断(-s 32)或调用次数过多 增大 -s 值;使用 -e trace= 过滤无关调用