dmesg关键日志需精准过滤而非全览:用dmesg -t | grep -i "error\|warn\|fail\|unable"筛选,结合硬件总线关键词、模块名对照lsmod、addr2line定位源码,oom需联动ps/cgroup验证,警惕“无报错=无问题”盲区。

怎么看 dmesg 里真正有用的那几行
内核日志不是日志,是线索拼图——dmesg 默认刷屏全是初始化信息,真出问题时关键报错往往被淹没在千行启动日志里。重点不是“看全”,而是“过滤准”。
实操建议:
- 用
dmesg -T | grep -i "error\|warn\|fail\|unable"加时间戳筛选(-T需 root 或sudo权限) - 硬件类问题优先搜
pci、nvme、ata、usb等总线关键词,比如dmesg | grep -A2 -B2 nvme - 驱动加载失败常表现为
modprobe: FATAL: Module xxx not found,但内核实际可能已静默 fallback 到通用驱动,得结合lsmod和/proc/modules对照 - 别信
dmesg -c清空后“没报错=没问题”——有些错误只在设备热插拔或负载突增时触发,需配合dmesg -w实时盯梢
journalctl -k 和 dmesg 输出不一致?
因为它们来源不同:dmesg 直读内核环形缓冲区(log_buf),而 journalctl -k 读的是 systemd-journald 持久化后的内核日志副本——缓冲区满会丢老日志,journald 可能因配置丢字段或截断。
实操建议:
- 查最近一次重启前的错误,必须用
journalctl -k -b -1(-b -1表示上一次 boot) - 发现
journalctl -k有内容但dmesg没有,大概率是内核缓冲区溢出,调大kernel.printk_ratelimit或改kernel.log_buf_len(需 boot 参数) - 若
journalctl -k完全空白,检查journald是否禁用了内核日志捕获:grep -i "kmsg" /etc/systemd/journald.conf,确认ForwardToKMsg=是yes
从 dmesg 报错定位具体驱动或模块
内核错误行末尾常带 [xxxxx],那是模块名缩写,但不是源码模块名,而是内核符号表里注册的名称,和 lsmod 输出一致。
实操建议:
- 看到类似
nvme 0000:01:00.0: PCIe Bus Error: severity=Correctable,其中nvme就是模块名,直接lsmod | grep nvme看是否加载、版本号 - 报错含地址如
BUG: unable to handle kernel NULL pointer dereference at 0000000000000000,用addr2line -e /lib/modules/$(uname -r)/build/vmlinux 0000000000000000反查(需安装 debuginfo 包) - 某些驱动(如
igb、r8169)有多个变体,报错里模块名可能和lspci -k显示的Kernel driver in use不一致,此时以lspci -vv -s xx:xx.x | grep -A10 "Kernel modules"为准
为什么 dmesg 里有 OOM killer 记录却找不到进程被杀
OOM killer 日志(Killed process xxx (xxx) total-vm:xxxxkB, anon-rss:xxxxkB, file-rss:0kB)只记录它动手那一刻的状态,但进程可能已退出、被信号终止,或被容器 runtime 拦截并静默回收。
实操建议:
- OOM 日志本身不含 PID 命令行,需立刻执行
ps aux --sort=-%mem | head -20对照内存占用峰值 - 容器环境(Docker/Podman)中,OOM 由 cgroup v1/v2 触发,
dmesg记录的是内核视角,实际 kill 由 runc 或 crun 执行,查docker ps -a或podman ps -a看状态为Exited (137) - 检查
/sys/fs/cgroup/memory/下对应 cgroup 的memory.oom_control和memory.events,确认是否启用 OOM killer
内核日志最危险的盲区不是看不懂报错,而是把“没报错”当结论——很多硬件降级、驱动静默 fallback、cgroup 节流都不会打 ERROR,只在 /proc 或 sysfs 留痕迹。










