挂起进程通常不写入常规应用日志,因其是内核响应信号(如sigstop)后的正常状态,而非错误事件;唯一直接线索是dmesg和/proc/[pid]/status,/var/log/messages极少记录挂起本身,仅可能留存oom killer等间接痕迹。

进程因资源受限而挂起,通常不会直接写入常规应用日志,而是由内核在资源分配失败时触发信号(如 SIGSTOP)或直接拒绝调度——这种情况下,dmesg 和 /proc/[pid]/status 是唯一直接线索,/var/log/messages 很少记录“挂起”,但可能留下 OOM killer 杀进程的痕迹。
为什么 ps aux | grep T 看到挂起进程,却找不到对应日志?
因为挂起(state T)本身不是错误事件,而是进程响应信号(如 SIGSTOP、SIGTSTP)后的正常状态。内核不为此打日志;只有当挂起导致后续超时、资源耗尽或被 OOM killer 干掉时,才可能留下间接痕迹。
常见诱因包括:
- 手动执行了
kill -STOP [pid]或按了Ctrl+Z - 调试器(如
gdb)附加后自动暂停 - 父进程调用
ptrace()进入追踪模式 - 容器 runtime(如
containerd)因 cgroup 内存/ CPU 限额触发冻结(Freezer cgroup),此时进程 state 变为T,但内核会记录到dmesg
查 Freezer cgroup 是否冻结了进程
如果进程跑在 systemd 或容器中,挂起很可能是被 cgroup 冻结所致。检查路径是否存在并读取状态:
cat /sys/fs/cgroup/freezer/<em>your-cgroup-path</em>/freezer.state
若输出为 FROZEN,说明该 cgroup 下所有进程都被挂起,且内核会在 dmesg 中记录类似:
freezer: Freezing of cgroup /system.slice/myapp.service aborted
或更常见的:
freezer: Freezing cgroup /docker/abc123... failed: -EBUSY
注意:/sys/fs/cgroup/freezer/ 在较新内核(5.11+)中已被移除,改用 systemd 的 TasksMax= 或 MemoryAccounting= 配合 systemctl show myapp.service 查 FreezerState= 字段。
从 dmesg 挖 OOM 或资源拒绝线索
资源受限最常表现为内存不足(OOM)或文件描述符耗尽,这些会触发内核日志:
-
dmesg -T | grep -i "killed process"—— 找 OOM killer 杀进程记录 -
dmesg -T | grep -A2 -B2 "Out of memory"—— 定位具体时间点 -
dmesg -T | grep -i "too many open files"—— 查看是否因ulimit -n超限被拒绝打开文件,进而阻塞 -
dmesg -T | grep -i "cgroup.*memory"—— 容器场景下内存限额触发的冻结或 kill
注意:这些日志只保留在 ring buffer 中,默认最多保留最近若干 MB,重启后丢失。长期排查建议开启 kernel.dmesg_restrict=0 并配合 rsyslog 将 kern.* 转存到磁盘。
确认进程当前资源限制和实际占用
仅靠日志不够,必须对照进程实时资源视图:
- 查硬限制:
cat /proc/[pid]/limits—— 特别关注Max open files、Max processes、Max locked memory - 查当前使用:
cat /proc/[pid]/status | grep -E "Threads|VmRSS|FDSize|SigQ"——VmRSS是实际物理内存占用,FDSize是已分配文件描述符槽位数 - 查句柄详情:
ls -l /proc/[pid]/fd/ | wc -l—— 实际打开的 fd 数量,对比ulimit -n输出
如果 FDSize 接近或等于 Max open files,且进程卡在 read() 或 accept(),基本可断定是 fd 耗尽导致挂起等待。
真正难定位的是 cgroup 冻结和 ptrace 调试挂起——它们不留应用层日志,也不进 /var/log/,唯一可靠入口是 /proc/[pid]/status 中的 State: T (stopped) 和 TracerPid(非 0 表示被调试器 attach)或 Cpus_allowed_list(全 0 表示被 CPU cgroup 禁用执行)。别指望日志告诉你“为什么挂”,得靠状态反推。











