10_strace和ftrace
约 876 字大约 3 分钟
2025-10-14
在运维排查中,经常会遇到 某个进程或者Service 无法正常工作的问题。
一般处理方式都是去看 该进程或者Service 的运行日志和启动日志,此时如果研发没有写好这些日志的处理逻辑的话,则日志里面就获得不了啥有用的信息。
而strace命令提供了一种新的排查思路,通过使用strace命令,我们得以看到进程此时的全部系统调用的内容和返回结果, 以此来判断进程此时的全部系统调用,进而判断整个程序卡在哪个点上。
工具比较
| 工具 | 关注层级 | 核心用途 |
|---|---|---|
| strace | 用户态 ↔ 内核接口(系统调用) | 跟踪程序调用了哪些系统调用、参数与返回值是什么 |
| ftrace | 内核内部 | 跟踪内核函数执行、性能、延迟、调度等更底层行为 |
形象比喻
- strace:像是在门口看人进出
➜ 记录程序“请求系统”的所有系统调用(如open、read、write、socket)。 - ftrace:像是进去屋里观察内核内部
➜ 分析具体内核函数执行流程、延迟、CPU 调度、软中断等。
常见误区及解决
| 常见误区 | 原因 | 正确做法 |
|---|---|---|
| strace 一开全屏刷日志,看不懂 | 系统调用的次数是非常密集的 | 用 -e trace=open,read,write 过滤 |
| 忘记 root 权限跑 ftrace | ftrace 需要较高权限 | 使用 sudo 或切 root |
| 误以为 ftrace 是命令 | 其实是内核子系统,不是一条命令 | 通过 /sys/kernel/debug/tracing 或 trace-cmd 使用 |
| 想用 strace 分析内核问题 | strace 只能看用户态调用 | 内核卡死问题需用 ftrace |
strace 示例
假设现在 snmpd 进程无法正常启动,对应的进程号是:100815。对应的错误日志没有更进一步的信息,此时 可以通过strace命令来查看该进程此时的系统调用。
strace -tt -e trace=open,read,write -p 100815 2> trace.log选项说明
| 选项 | 作用 |
|---|---|
-tt | 打印时间戳,分析延迟或卡住位置 |
-p 100815 | 附加到目标进程 |
-e trace=... | 只跟踪指定系统调用,减少噪音 |
2> trace.log | 把结果写入日志文件 |
注意 strace命令的系统开销比较大,尽量不要长时间的跑该命令。
下列的故障返回里面的: ENOENT和 **"EACCES"**是POSIX(Portable Operating System Interface)标准中定义的系统错误码(errno 值),常用于 Unix-like 系统(如 Linux、macOS)中的文件操作系统调用。
当使用strace命令抓到系统调用的错误返回后,遇到不清楚的错误码时, 我们就可以查看POSIX的官网对应的说明: https://docs.particle.io/reference/device-os/api/debugging/posix-errors/; 当然也可以直接丢给AI(much easy!)
常见故障类型及 strace 命令定位
| 故障类型 | 在 strace 中会看到的特征系统调用 |
|---|---|
| ❗ 配置文件缺失 / 路径错误 | open(...) = -1 ENOENT (No such file or directory) |
| 🔒 权限不足 | open(...) = -1 EACCES (Permission denied) |
| 🧊 程序卡死 / 卡在 IO 或系统调用 | 一直重复 read(...) 或卡在 futex(...) 没有返回 |
| 🛑 端口被占用 / 绑定失败 | bind(...) = -1 EADDRINUSE |
| 🔗 DNS / 网络问题 | connect(...)、getaddrinfo(...) 长时间无响应 |
| 💥 崩溃 / 信号异常 | --- SIGSEGV、SIGABRT、SIGKILL 等信号信息 |
| 🧬 库文件缺失 (动态库) | open("/lib/...", O_RDONLY) = -1 ENOENT |
| 🧵 多线程死锁 | 大量 futex(...) 或 nanosleep(...) 重复 |
