strace命令,查看进程的系统调用
约 843 字大约 3 分钟
2025-10-14
在运维排查中,经常会遇到某个进程无法正常工作的问题。一般处理方式都是去看该进程的运行日志和启动日志,此时研发没有写好这些日志的处理逻辑的话,则无法获得有用的信息。
而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)中的文件操作系统调用。
当遇到不清楚的错误码时,可以查看POSIX的官网对应的说明: https://docs.particle.io/reference/device-os/api/debugging/posix-errors/
常见故障类型及 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(...) 重复 |
