3,770
社区成员




调试Linux驱动程序是内核开发中的重要环节,需要结合内核特性、调试工具和驱动特性进行针对性处理。以下是常用的调试方法和工具链:
打印调试(printk)
最常用的基础调试方式,通过内核打印函数输出信息:
// 不同日志级别(优先级从高到低)
printk(KERN_EMERG "紧急错误\n"); // 系统不可用
printk(KERN_ALERT "必须立即处理\n");
printk(KERN_CRIT "严重情况\n");
printk(KERN_ERR "错误信息\n");
printk(KERN_WARNING "警告信息\n");
printk(KERN_NOTICE "正常但重要的信息\n");
printk(KERN_INFO "提示信息\n");
printk(KERN_DEBUG "调试信息\n"); // 默认不显示,需配置内核日志级别
dmesg
或 cat /var/log/kern.log
echo 8 > /proc/sys/kernel/printk
(显示所有级别)内核恐慌(Kernel Panic)分析
驱动崩溃可能导致内核恐慌,可通过以下方式定位:
CONFIG_DEBUG_INFO=y
Call Trace
),可结合 addr2line
转换地址为代码行: addr2line -e vmlinux 0xffffffff81234567 # vmlinux为带符号的内核镜像
GDB 远程调试
通过 qemu
或硬件调试器(如 J-Link)实现内核/驱动的断点调试:
CONFIG_DEBUG_INFO=y
和 CONFIG_DEBUG_KERNEL=y
# 目标机启动时添加内核参数
kgdboc=ttyS0,115200 # 串口调试
# 主机连接
gdb vmlinux
(gdb) target remote /dev/ttyS0 # 连接目标机串口
(gdb) break driver_function # 设置断点
(gdb) c # 继续执行
ftrace 跟踪函数调用
用于跟踪驱动函数的调用流程、耗时等,无需修改代码:
mount -t debugfs nodev /sys/kernel/debug
echo function > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/tracing_on
cat /sys/kernel/debug/tracing/trace
echo my_driver_func > /sys/kernel/debug/tracing/set_ftrace_filter
kprobe 动态钩子
无需重新编译内核,在运行时对函数设置钩子,捕获参数和返回值:
# 安装kprobe工具(如systemtap或bpftrace)
bpftrace -e 'kprobe:my_driver_func { printf("args: %x\n", arg0); }'
内存泄漏检测
kmalloc
/kfree
不匹配是常见问题,可使用: slub_debug
:内核参数添加 slub_debug=UZ
,启用 slab 分配器调试,检测重复释放、越界等。 kmemleak
:内核配置 CONFIG_DEBUG_KMEMLEAK=y
,通过 echo scan > /sys/kernel/debug/kmemleak
触发扫描,查看 /sys/kernel/debug/kmemleak
报告泄漏点。资源竞争与死锁
lockdep
:内核配置 CONFIG_LOCKDEP=y
,启用后会在死锁发生时输出详细的锁依赖关系日志。 watchdog
:内核 watchdog 机制会在系统无响应时触发重启,日志中会包含死锁前的调用栈。查看设备树与硬件信息
ls /proc/device-tree/ # 查看设备树节点
lspci/lsusb # 查看PCI/USB设备信息
寄存器与I/O调试
devmem 0x12345678 # 读取物理地址0x12345678的寄存器值
devmem 0x12345678 w 0x1234 # 写入值0x1234
工具/方法 | 用途 | 适用场景 |
---|---|---|
printk | 输出调试信息 | 简单流程跟踪、变量值查看 |
gdb + kgdb | 断点调试、调用栈分析 | 复杂逻辑调试 |
ftrace | 函数调用跟踪、耗时统计 | 性能瓶颈分析、流程梳理 |
kmemleak | 内存泄漏检测 | 长期运行的驱动稳定性测试 |
lockdep | 锁竞争与死锁检测 | 多线程/中断上下文的同步问题 |
bpftrace | 动态追踪内核函数参数与返回值 | 无需修改代码的临时调试 |
strace
查看用户态程序调用驱动的系统调用是否正常,再深入内核调试。 CONFIG_DEBUG_FS
、CONFIG_DEBUG_KERNEL
等调试选项,增强内核自检能力。 根据驱动类型(字符设备、块设备、网络设备等)和具体问题(崩溃、性能、功能异常),选择合适的工具组合可大幅提高调试效率。