本页目录

调试与测试

覆盖: printk/dynamic debug → KGDB → KUnit → kselftest → LTP → syzkaller → fault injection → lockdep 集成 内核版本: 2.6 ~ 6.x

printk: 内核日志

// kernel/printk/printk.c
printk(KERN_ERR "error: %d\n", err);

// 日志等级过滤:
//   KERN_EMERG(0) KERN_ALERT(1) KERN_CRIT(2) KERN_ERR(3)
//   KERN_WARNING(4) KERN_NOTICE(5) KERN_INFO(6) KERN_DEBUG(7)

// 控制台输出过滤:
echo 4 > /proc/sys/kernel/printk  // 只输出 ERROR 及以上到控制台

// 5.x+ 结构化日志: dev_printk, pr_fmt

Dynamic Debug

# 按模块/函数/文件/行号开启调试日志 (runtime, 不需要重编)
echo "module nfs +p" > /sys/kernel/debug/dynamic_debug/control
echo "func tcp_rcv_established +p" > dynamic_debug/control
echo "file fs/nfs/* +p" > dynamic_debug/control
# p=printk, f=include func name, l=include line, t=include thread id

# 查看已启用条目
cat /sys/kernel/debug/dynamic_debug/control | grep "=p"

KGDB: 内核级 GDB

# 通过串口远程调试内核 (类似 gdbserver)
# boot: kgdboc=ttyS0,115200 kgdbwait
# gdb vmlinux → target remote /dev/ttyS0 → 设断点, 单步
# SysRq-g 进入 KGDB

echo g > /proc/sysrq-trigger  # 触发进入 KGDB

KUnit: 内核单元测试

// lib/kunit/
// 类似用户态单元测试框架, 完全在内核内执行
#include <kunit/test.h>

static void my_test(struct kunit *test) {
    KUNIT_EXPECT_EQ(test, my_function(42), 84);
}

static struct kunit_case my_test_cases[] = {
    KUNIT_CASE(my_test),
    {},
};

// 运行: 编译时内置 → 启动时自动执行 → 结果在 dmesg

kselftest: 内核自测试套件

# 内核自包含测试 (tools/testing/selftests/)
make -C tools/testing/selftests TARGETS=net run_tests
make -C tools/testing/selftests TARGETS=bpf run_tests

# 覆盖: 系统调用, 内存管理, 网络, BPF, 文件系统, ...

Syzkaller: 模糊测试

Syzkaller:覆盖率引导的无监督内核 Fuzzer 生成随机 syscall 序列 (覆盖率引导) QEMU VM 中执行 检测 crash / hang 复现 + 报告 (自动 bisect) 已发现 5000+ 内核 bug —— 覆盖率引导的随机 syscall 序列持续在 QEMU 里挖掘 crash/hang 部署:github.com/google/syzkaller

LTP (Linux Test Project)

# 最大的内核/glibc 回归测试套件 (github.com/linux-test-project/ltp)
./runltp -f syscalls       # 系统调用测试
./runltp -f mm             # 内存管理
./runltp -f fs             # 文件系统

Fault Injection

# 故障注入框架: 模拟各种硬件/内存/IO 故障
# 检查错误处理路径是否正确

# 内存分配失败:
echo 100 > /sys/kernel/debug/failslab/interval  # 每 100 次 slab alloc → fail 1 次

# IO 错误:
echo 1 > /sys/kernel/debug/fail_make_request/times

参考

  • 源码⁠: kernel/printk/, kernel/debug/, lib/kunit/, tools/testing/selftests/
  • 内核文档⁠: Documentation/dev-tools/, Documentation/admin-guide/dynamic-debug-howto.rst
  • 工具⁠: syzkaller (github.com/google/syzkaller), LTP (github.com/linux-test-project/ltp)

关键词: printk, dynamic debug, KGDB, KUnit, kselftest, syzkaller, LTP, fault injection