插件窝 干货文章 Linux系统中的高级内核模块调试方法汇总结

Linux系统中的高级内核模块调试方法汇总结

DEBUG 调试 内核 kernel 724    来源:    2025-05-13

Linux高级内核模块调试方法汇总

1. printk调试

printk是内核中最基本的调试方法,类似于用户空间的printf。

printk(KERN_DEBUG "Debug message: value=%d\n", var);

等级说明

  • KERN_EMERG (0): 紧急消息
  • KERN_ALERT (1): 需要立即处理
  • KERN_CRIT (2): 关键条件
  • KERN_ERR (3): 错误条件
  • KERN_WARNING (4): 警告条件
  • KERN_NOTICE (5): 正常但重要
  • KERN_INFO (6): 信息性消息
  • KERN_DEBUG (7): 调试级消息

查看日志

dmesg -H       # 人性化显示
dmesg -w       # 实时监视
dmesg -l debug # 只显示debug级别消息

2. 动态调试(dynamic debug)

更灵活的printk替代方案,可以运行时启用/禁用调试消息。

pr_debug("Debug message with %s\n", "dynamic debug");

配置方法:

# 查看所有可调试点
cat /sys/kernel/debug/dynamic_debug/control

# 启用特定文件的调试
echo 'file module.c +p' > /sys/kernel/debug/dynamic_debug/control

# 启用特定函数的调试
echo 'func foo +p' > /sys/kernel/debug/dynamic_debug/control

3. kprobes调试

kprobes允许在内核的任何指令处设置断点。

基本用法

# 安装kprobe工具
apt-get install linux-tools-$(uname -r)

# 跟踪特定函数
perf probe --add vfs_read
perf stat -e probe:vfs_read -a sleep 10
perf probe --del vfs_read

通过debugfs使用kprobes

# 列出所有可探测的函数
cat /proc/kallsyms | grep function_name

# 设置探测点
echo 'p:myprobe do_sys_open' > /sys/kernel/debug/tracing/kprobe_events
echo 1 > /sys/kernel/debug/tracing/events/kprobes/myprobe/enable

# 查看结果
cat /sys/kernel/debug/tracing/trace_pipe

4. ftrace调试

ftrace是内核内置的函数跟踪器。

基本用法

# 启用ftrace
echo function > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/tracing_on

# 查看结果
cat /sys/kernel/debug/tracing/trace

# 只跟踪特定函数
echo schedule > /sys/kernel/debug/tracing/set_ftrace_filter

高级功能

# 函数图跟踪
echo function_graph > /sys/kernel/debug/tracing/current_tracer

# 跟踪特定进程
echo $$ > /sys/kernel/debug/tracing/set_ftrace_pid

# 跟踪特定模块
echo ':mod:module_name' > /sys/kernel/debug/tracing/set_ftrace_filter

5. SystemTap调试

SystemTap提供了强大的脚本语言来监控和分析运行中的Linux系统。

基本示例

probe kernel.function("sys_open") {
    printf("%s(%s)\n", probefunc(), user_string($filename))
}

常用命令

stap -ve 'probe begin { log("hello world") exit() }'
stap -L 'kernel.function("vfs_read")'
stap script.stp -o output.log

6. KGDB调试

KGDB允许通过串口或网络对Linux内核进行源代码级调试。

配置步骤

  1. 在内核配置中启用KGDB
  2. 添加启动参数:kgdboc=ttyS0,115200 kgdbwait
  3. 使用gdb连接目标机

GDB命令

target remote /dev/ttyS0
break function_name
continue

7. Kdump和Crash工具

用于分析内核崩溃转储。

配置Kdump

# 安装必要工具
apt-get install kdump-tools crash

# 配置/etc/default/kdump-tools
KDUMP_COREDIR="/var/crash"

使用Crash分析

crash /usr/lib/debug/boot/vmlinux-$(uname -r) /var/crash/dump.20191010

常用命令:

bt      # 查看调用栈
log     # 查看内核日志
kmem    # 查看内存信息
task    # 查看任务信息

8. 内存调试工具

KASAN (Kernel Address Sanitizer)

用于检测内存错误,如越界访问、释放后使用等。

配置内核选项:

CONFIG_KASAN=y
CONFIG_KASAN_INLINE=y

kmemleak

用于检测内核内存泄漏。

# 启用
echo scan > /sys/kernel/debug/kmemleak

# 查看报告
cat /sys/kernel/debug/kmemleak

9. 性能分析工具

perf工具

perf top                 # 实时查看热点函数
perf record -a -g        # 记录性能数据
perf report              # 分析记录数据
perf stat -e instructions,cache-misses ./program

BPF工具(BCC/BPFtrace)

# 使用BCC工具
/usr/share/bcc/tools/execsnoop

# 使用BPFtrace
bpftrace -e 'tracepoint:syscalls:sys_enter_open { printf("%s %s\n", comm, str(args->filename)); }'

10. 模块调试技巧

模块加载/卸载调试

# 查看模块依赖
modinfo module_name

# 加载模块时打印调试信息
insmod module.ko dyndbg=+p

# 查看模块参数
cat /sys/module/module_name/parameters/*

调试Oops消息

当内核遇到严重错误时会产生Oops消息,包含: - 错误类型和地址 - CPU寄存器状态 - 调用栈回溯

分析方法: 1. 确保内核配置了CONFIG_DEBUG_INFO=y 2. 使用gdb或crash工具分析Oops消息

总结

根据调试场景选择合适的方法: - 简单调试:printk/dynamic debug - 函数调用跟踪:ftrace/kprobes - 复杂逻辑分析:SystemTap/BPF - 崩溃分析:Kdump/crash - 内存问题:KASAN/kmemleak - 性能分析:perf/BPF

掌握这些工具的组合使用可以高效定位各种内核模块问题。