Linux内核调试是系统开发和故障排查中的重要技能。以下是全面的调试方法分类和操作指南:
printk(内核日志)
printk(KERN_DEBUG "Debug message: val=%d\n", var);
KERN_EMERG
(0) 到 KERN_DEBUG
(7)bash
dmesg -T | tail -20 # 带时间戳显示最近20条
cat /proc/sys/kernel/printk # 查看当前日志级别
echo 8 > /proc/sys/kernel/printk # 启用所有级别输出
动态调试(Dynamic Debug)
echo 'file *.c +p' > /sys/kernel/debug/dynamic_debug/control
# 启用某文件所有printk
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
bash
kgdboc=ttyS0,115200 kgdbwait
bash
gdb vmlinux
(gdb) target remote /dev/ttyS0
bash
qemu-system-x86_64 -kernel bzImage -append "nokaslr root=/dev/sda" -S -s
# 主机另一终端
gdb vmlinux
(gdb) target remote :1234
(gdb) b start_kernel
bash
stap -e 'probe kernel.function("sys_open") { log("open: " . filename) }'
bash
perf probe --add tcp_sendmsg # 添加探针
perf stat -e cache-misses ls # 统计事件
perf record -g -p <PID> # 采样调用栈
kdump/crash
bash
kexec -p /boot/vmlinuz --initrd=/boot/initrd.img --append="crashkernel=256M"
bash
crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux vmcore
Oops消息分析
[]
内)ftrace
echo function > /sys/kernel/debug/tracing/current_tracer
echo __do_page_fault > /sys/kernel/debug/tracing/set_ftrace_filter
cat /sys/kernel/debug/tracing/trace_pipe
BPF (eBPF)
bpftrace -e 'kprobe:do_sys_open { printf("%s: %s\n", comm, str(arg1)) }'
KASAN(内存错误检测)
CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y
BUG: KASAN: slab-out-of-bounds in kmalloc_oob_right+0x3c/0x50
slub_debug
echo 1 > /sys/kernel/slab/<slab_cache>/trace
生产环境谨慎使用
KGDB
或KDB
在生产环境使用(可能导致系统冻结)printk
过量可能引发日志风暴内核版本适配
符号信息
vmlinux
)或编译CONFIG_DEBUG_INFO=y
场景 | 推荐工具 |
---|---|
快速日志调试 | printk + dynamic_debug |
崩溃分析 | kdump + crash |
动态跟踪 | ftrace + BPF |
开发环境单步调试 | QEMU+GDB |
内存错误检测 | KASAN + slub_debug |
掌握这些工具后,90%以上的内核问题都能有效定位。实际使用时建议从非侵入式工具(如printk/ftrace)开始,逐步过渡到复杂调试方案。