dmesg -w 无法稳定捕获非法内存访问日志,因kasan/smap/smep等需编译启用、启动参数配置及日志级别调高,且须用dmesg -w -t -l err,warn,alert,emerg | grep -i -e "(oops|panic|kasan|use-after-free|out of bounds)"组合过滤关键线索。

直接用 dmesg -w 无法稳定捕获非法内存访问触发的内核自保护日志(如 KASAN、KMSAN、SMAP/SMEP 违规、Oops、panic),因为这类事件多数不走标准 printk 流,或被内核静默抑制,或需额外配置才能输出。
必须先确认内核是否启用相关检测机制
非法内存访问本身不会自动产生 dmesg 日志——除非你已开启对应调试功能:
-
KASAN(Kernel Address Sanitizer):需编译时启用
CONFIG_KASAN=y或CONFIG_KASAN_GENERIC/CONFIG_KASAN_SW_TAGS,且启动参数含kasan=on;否则即使发生越界访问,也不会打印堆栈和错误描述。 -
SMAP/SMEP 触发的 #PF 异常:默认只记为普通 page fault,不会标记为“非法访问”;需配合
kernel.printk调高日志级别(如echo "8 4 1 7" > /proc/sys/kernel/printk),并确保CONFIG_X86_PAT和CONFIG_DEBUG_PAGEALLOC已启用。 -
Oops/Panic 日志:依赖
CONFIG_PRINTK(必须开启),且不能被loglevel=启动参数压制(如loglevel=3会屏蔽 warn 及以下)。
实时监控要加过滤+时间+高亮
即使机制已启用,原始 dmesg -w 输出仍混杂大量无关信息。推荐组合命令:
dmesg -w -T -l err,warn,alert,emerg | grep -i -E "(oops|panic|bug|invalid|access.*denied|page.*fault|kasan|slab|use-after-free|double-free|out of bounds)"
-
-T确保你能对齐故障发生时刻(比如你刚运行一个可疑程序,立刻看时间戳是否匹配); -
-l锁定高危级别,避免被 info 日志淹没; -
grep模式覆盖常见非法访问关键词,注意大小写不敏感(-i)和多关键词或匹配(-E)。
关键信号不止在日志级别字段里
很多真实非法访问不会标为 err 级别,而是以 info 或 debug 发出,但消息体含关键线索:
BUG: unable to handle kernel NULL pointer dereference at (null)-
kernel tried to execute executable page from non-executable memory(SMEP 违规) KASAN: use-after-free in xxx+0x123/0x456-
general protection fault: 0000 [#1] SMP(典型 Oops 开头)
所以不能只信 -l err,必须靠 grep 扫正文。
更可靠的替代路径
若 dmesg -w 始终无响应,说明日志未生成或被截断。此时应:
- 检查
/proc/sys/kernel/kptr_restrict:值为2会隐藏函数地址,设为0才能看到完整 Oops 栈; - 查
journalctl -k -f:systemd journal 有时比 dmesg 缓冲区保留更久,尤其在启用了Storage=persistent时; - 看
/var/log/kern.log(如果 rsyslog/rsyslogd 配置了 kern.* 转储); - 崩溃后立即执行
dmesg -T > /tmp/dmesg-crash.log,避免缓冲区被后续日志覆盖。
不复杂但容易忽略:非法内存访问的日志不是“总会出来”,而是“你配好了它才出来”。











