当前位置: 首页 > news >正文

strace的常用案例

这是面向初学者与日常运维/开发的 strace 学习说明与操作案例,覆盖安装、核心概念、常用选项、典型问题的排查步骤与解读方法。

一、strace 是什么

  • 作用:跟踪进程的系统调用(syscall)与信号,展示每个调用的参数、返回值、耗时等,用于定位“程序和内核交互”层面的问题(文件、网络、权限、进程、内存、时间、线程同步等)。
  • 适用场景:
    • 程序“卡住/变慢”在哪里?
    • 为什么报 No such file or directory / Permission denied?
    • 进程在访问哪些文件/网络?
    • 动态库/配置文件加载路径问题
  • 注意事项:
    • 对被跟踪进程有一定性能影响(尤其是大量 I/O 时),生产环境请谨慎。
    • 需要足够权限(对别的进程常需 root 或设置 ptrace 权限)。
    • 某些安全策略(如 Yama ptrace_scope、容器安全设置)会限制附加。

二、安装与基本用法

  • 安装:
    • Debian/Ubuntu: sudo apt-get install strace
    • CentOS/RHEL: sudo yum install strace 或 dnf install strace
    • Alpine: apk add strace
  • 基本运行:
    • 新启动并跟踪:strace
    • 附加到已有进程:sudo strace -p
    • 输出到文件:strace -o trace.log

三、常用选项速览

  • 跟踪范围
    • -e trace= 只跟踪某类或某些 syscall,如:
      • -e trace=file 关注文件相关(openat/stat/access 等)
      • -e trace=network 关注网络(socket/connect/sendto/recvfrom 等)
      • -e trace=process/fault/signal/ipc 等
    • -e trace=openat,stat,access 精确到单个/多个 syscall
    • -P 仅追踪命中该路径的文件操作(内核新一点的 strace 支持)
  • 进程/线程
    • -p 附加
    • -f 跟踪子进程/线程(fork/vfork/clone)
    • -ff 配合 -o file 使用,按 PID 分文件输出 file.
  • 输出控制与细节
    • -o 写文件
    • -s 增加字符串截断长度(默认 32),如 -s 200
    • -v 更详细地打印结构体/标志位
    • -y 打印文件描述符对应的路径
    • -yy 打印套接字/文件描述符的“解码信息”(如协议、目标)
    • -k 打印内核调用栈(需要内核支持,调试符号)
  • 时间与统计
    • -tt/-ttt 打印时间戳(微秒/Unix 时间)
    • -T 打印每个 syscall 耗时
    • -c 统计模式:结束时输出各 syscall 次数、耗时占比、失败率
  • 高级与实验
    • -e inject=… 可做错误注入/延迟(版本需较新,慎用)
    • -D 将跟踪工作放入子进程,降低对被跟踪程序干扰

四、快速上手练习(由浅入深)
练习 1:观察一个命令读取了哪些文件

  • 目的:理解 openat/stat/access 等调用与路径搜索
  • 命令:
    • strace -o trace.log -e trace=file -s 200 ls /tmp
  • 关注点:
    • 动态库加载:openat(…, “/lib/x86_64-linux-gnu/…”, O_RDONLY|O_CLOEXEC) = fd
    • 配置/本地文件:openat(AT_FDCWD, “/etc/ld.so.cache”, O_RDONLY|…) …
    • 找不到文件返回:ENOENT (No such file or directory)

练习 2:只看网络连接与 DNS 查询

  • 命令:
    • strace -e trace=network -s 200 curl http://example.com
  • 搭配:
    • strace -e trace=file,network -s 200 curl http://example.com
  • 解读:
    • socket(AF_INET/AF_INET6, …)
    • connect(…) = -1 ETIMEDOUT / ECONNREFUSED 代表超时或被拒绝
    • 还会看到对 /etc/resolv.conf、/etc/hosts 的读取(DNS 配置)

练习 3:统计程序花费时间在哪些系统调用

  • 命令:
    • strace -c your_program
  • 输出解读(示例):
    • read/write/futex 比例很高 → I/O 瓶颈或锁争用
    • clock_gettime 开销大 → 频繁获取时间
    • 如果有大量失败率高的调用(如 ENOENT 的 stat)可能是路径探测过多

练习 4:跟踪子进程与更丰富输出

  • 命令:
    • strace -f -o trace.log -s 200 -yy -tt -T your_program
  • 说明:
    • -f 跟踪子进程/线程,-yy 解码 FD/套接字,-tt 打印时间戳,-T 打印耗时
    • 大程序/服务建议使用 -ff -o trace 让每个 PID 打到 trace.

练习 5:附加到卡住的进程看看在等什么

  • 命令:
    • sudo strace -p -s 200 -tt -T
  • 常见卡点:
    • futex(…, FUTEX_WAIT, …) 长时间不返回 → 线程锁等待
    • read(…, fd=0/管道/套接字) 阻塞 → 上游没写数据
    • connect/send/recv 阻塞 → 网络不通/对端无响应
    • openat/stat 反复访问同一文件 → 配置或路径问题

五、典型问题排查案例

案例 1:程序报 No such file or directory,但文件明明在

  • 现象:./app 报错:No such file or directory
  • 排查步骤:
    1. strace -e trace=file -s 200 ./app
    2. 关注最后失败的 openat/execve 行
      • 若 execve(“./app”, …) = -1 ENOENT,可能是架构/动态链接器问题(如缺少 /lib64/ld-linux-x86-64.so.2),不是当前目录没有该文件
      • 若 openat(AT_FDCWD, “config.yaml”, …) = -1 ENOENT,说明相对路径问题,程序工作目录不对
    3. 解决:
      • 使用绝对路径或调整工作目录
      • 检查 ldd ./app 动态库是否缺失;安装所需库或设置 LD_LIBRARY_PATH

案例 2:命令行工具启动很慢

  • 现象:启动数秒后才输出
  • 操作:
    • strace -tt -T -e trace=file,network -s 200 cmd
  • 观察:
    • 对 /etc/hosts、/etc/resolv.conf、~/.config 等大量 stat/open 操作是否失败且反复
    • connect 到某地址耗时很长(connect(…) = -1 ETIMEDOUT <5.000000>)
  • 解决:
    • 修正 DNS/网络配置或禁用不必要的网络探测
    • 减少无效路径探测(配置缓存)

案例 3:Web 服务偶发 5xx,怀疑文件句柄耗尽

  • 操作:
    • sudo strace -p -s 200 -tt -T -e trace=file
  • 观察:
    • openat 频繁成功但 close 极少 → FD 泄漏
    • 使用 -y 可把 fd 对应路径打印出来,定位未关闭的文件或 socket
  • 进一步:
    • lsof -p 查看句柄数量;修复代码路径加 close()

案例 4:容器内网络不通

  • 操作:
    • strace -e trace=network -yy curl http://service:8080
  • 观察:
    • connect(fd=3<socket:[…], AF_INET 10.0.0.5:8080) = -1 EACCES/ENETUNREACH
  • 方向:
    • 容器网络策略、iptables、主机防火墙、DNS 解析

案例 5:多进程程序分叉行为

  • 操作:
    • strace -ff -o trace -s 200 -f server
  • 观察:
    • trace. 中寻找 fork/clone/execve 调用链,定位是哪个子进程出错

六、输出阅读技巧

  • 基本格式:
    • syscall(arg1, arg2, …) = return_value errno
    • errno 如 ENOENT/EPERM/EACCES/EAGAIN 提示原因
  • 常见文件相关 syscall:
    • openat/stat/access/read/write/close/getdents64
  • 常见网络相关 syscall:
    • socket/connect/bind/listen/accept/sendto/recvfrom/setsockopt/getaddrinfo 期间的文件读取
  • 字符串截断:
    • 看到 “…” 说明被截断,使用 -s 200 或更大
  • 时间定位:
    • 用 -tt 和 -T 快速找到耗时调用

七、权限与环境注意

  • 需要能 ptrace 目标进程:
    • echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope(临时放宽,谨慎)
    • 或以 root 身份运行
  • setuid 程序可能受限制;容器中需 CAP_SYS_PTRACE 等能力
  • 32/64 位混合环境可能显示不同的调用名称(如 open vs openat)

八、常用小抄

  • 跟踪文件调用并保存:
    • strace -e trace=file -s 200 -o file.log
  • 跟踪网络:
    • strace -e trace=network -yy
  • 统计耗时:
    • strace -c
  • 附加到卡住的进程:
    • sudo strace -p -s 200 -tt -T
  • 跟踪子进程并分文件:
    • strace -ff -o trace -f

九、进一步学习

  • man strace 查看全量选项与示例
  • 结合 ltrace(跟踪库调用)、perf/ftrace/bpf 工具形成多层排障组合
  • 在测试环境演练错误注入:-e inject=connect:error=ECONNREFUSED:when=3
http://www.dtcms.com/a/324528.html

相关文章:

  • 基于Qt/QML 5.14和YOLOv8的工业异常检测Demo:冲压点智能识别
  • VSCODE+GDB+QEMU调试内核
  • 为 Prometheus 告警规则增加 UI 管理能力
  • 力扣经典算法篇-47-Pow(x, n)(快速幂思路)
  • 每日算法刷题Day60:8.10:leetcode 队列5道题,用时2h
  • Java Stream流详解:从基础语法到实战应用
  • 安装1panel之后如何通过nginx代理访问
  • Linux系统编程Day11 -- 进程属性和常见进程
  • 智慧社区(十一)——Spring Boot 实现 Excel 导出、上传与数据导入全流程详解
  • Langchain调用MCP服务和工具
  • MySQL的逻辑架构和SQL执行的流程:
  • 正确使用SQL Server中的Hint(10)—Hint简介与Hint分类及语法(1)
  • Spring Boot + SSH 客户端:在浏览器中执行远程命令
  • 深入理解 Java 中的线程池:原理、参数与最佳实践
  • 【密码学】8. 密码协议
  • 金融机构在元宇宙中的业务开展与创新路径
  • 【教学类-29-06】20250809灰色门牌号-黏贴版(6层*5间层2间)题目和答案(剪贴卡片)
  • 使用Python调用OpenAI的function calling源码
  • Pytorch深度学习框架实战教程-番外篇02-Pytorch池化层概念定义、工作原理和作用
  • ROS2 QT 多线程功能包设计
  • PHP项目运行
  • (LeetCode 每日一题) 869. 重新排序得到 2 的幂 (哈希表+枚举)
  • Framework开发之Zygote进程2(基于开源的AOSP15)--init.rc在start zygote之后的事情(详细完整版逐行代码走读)
  • springboot骚操作
  • 【论文阅读】Deep Adversarial Multi-view Clustering Network
  • 视觉障碍物后处理
  • Java开发异步编程中常用的接口和类
  • 人工智能之数学基础:如何理解n个事件的独立?
  • [C/C++线程安全]_[中级]_[避免使用的C线程不安全函数]
  • Android APK 使用OpenGl 绘制三角形源码