这个场景解决什么
进程卡在不可中断状态、又不方便 attach 调试时,wchan 一列会直接告诉你它正睡在内核的哪个函数上:等磁盘 IO、等网络、等文件系统还是等用户态锁。结合 /proc/PID/stack 还能看到内核调用栈。它是排查 D 状态与卡顿的轻量手段,开销极低,也不会打扰目标进程。
基本信息
| 场景 | 进程状态异常但不想 attach 调试 |
|---|---|
| 组合方式 | ps 的 wchan 列 + /proc/PID/wchan + /proc/PID/stack |
| 特点 | 采样瞬时值,开销极低 |
| 权限 | 读取内核栈通常需要 root,权限不足时为空 |
典型使用场景
- 进程长期处于 D 状态,确认在等哪一类资源
- 服务卡顿但 CPU 不高,判断是否在等 IO 或锁
- 网络文件系统挂起导致进程不响应
- 批量巡检时快速筛出等待同一资源的进程
- 与 iostat、ss 的结果交叉验证方向
- 最小化环境里没有调试工具时定位卡点
轻量查看
轻量查看
ps -eo pid,stat,wchan:24,cmd | grep -E ' D|app-server' | head
cat /proc/1234/wchan; echo # 输出内核函数名
cat /proc/1234/stack 2>/dev/null | head # 内核栈,权限不足则为空
ps -eo stat,wchan:20,cmd | awk '$1 ~ /^D/' | head # 只看不可中断进程
for i in 1 2 3 4 5; do cat /proc/1234/wchan; echo; sleep 1; done # 多次采样常见 wchan 含义
| 内核函数 | 等待对象 | 关注方向 |
|---|---|---|
| io_schedule 及块层函数 | 磁盘 IO 完成 | 磁盘饱和或慢盘 |
| nfs 与 rpc 相关函数 | 网络文件系统响应 | 对端存储或网络 |
| futex 相关函数 | 用户态锁或条件变量 | 线程竞争与死锁 |
| ep_poll 等事件函数 | 事件循环空闲 | 通常是正常空闲状态 |
| tcp 接收相关函数 | 网络数据到达 | 对端或链路问题 |
wchan 显示的是采样瞬间的状态:微秒级的等待抓不到。判断疑似卡死时要多采几次,看是否长期停在同一个函数上。
内核版本与文件系统不同,函数名会不一样:含义要结合上下文判断,不要死记硬背具体字符串。
D 状态进程连信号都无法立刻响应,kill 不生效属于正常现象;真正的解法是消除它正在等待的资源,而不是反复发信号。