---
title: 调试与测试
url: https://doc.liz6.com/linux-kernel/11-kernel-development-and-build/02-debugging-and-testing
locale: zh
area: linux-kernel
tags:
- linux-kernel
- 内核开发与构建
date: 2026-06-30
modified: 2026-07-11
description: '覆盖: printk/dynamic debug → KGDB → KUnit → kselftest → LTP → syzkaller → fault injection → lockdep 集成 内核版本: 2.6 ~ 6.x'
---

# 调试与测试

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

## printk: 内核日志

```c
// 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

```bash
# 按模块/函数/文件/行号开启调试日志 (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

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

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

## KUnit: 内核单元测试

```c
// 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: 内核自测试套件

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

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

## Syzkaller: 模糊测试

<svg viewBox="0 0 720 260" xmlns="http://www.w3.org/2000/svg" font-family="-apple-system,'Source Han Sans CN','Microsoft YaHei',sans-serif" role="img" aria-label="Syzkaller 模糊测试流程:随机生成 syscall 序列到发现内核 bug">
  <defs><marker id="sk-arrow" markerWidth="10" markerHeight="8" refX="8" refY="3" orient="auto"><path d="M0,0 L8,3 L0,6 Z" fill="#475569"/></marker></defs>
  <rect width="720" height="260" fill="#ffffff"/>
  <text x="360" y="28" text-anchor="middle" font-size="17" font-weight="700" fill="#1f2933">Syzkaller:覆盖率引导的无监督内核 Fuzzer</text>
  <rect x="20" y="70" width="140" height="64" rx="6" fill="#e2e8f0"/>
  <text x="90" y="98" text-anchor="middle" font-size="12" font-weight="700" fill="#334155">生成随机 syscall 序列</text>
  <text x="90" y="116" text-anchor="middle" font-size="10" fill="#475569">(覆盖率引导)</text>
  <line x1="160" y1="102" x2="196" y2="102" stroke="#475569" stroke-width="1.6" marker-end="url(#sk-arrow)"/>
  <rect x="200" y="70" width="140" height="64" rx="6" fill="#e2e8f0"/>
  <text x="270" y="106" text-anchor="middle" font-size="12" font-weight="700" fill="#334155">QEMU VM 中执行</text>
  <line x1="340" y1="102" x2="376" y2="102" stroke="#475569" stroke-width="1.6" marker-end="url(#sk-arrow)"/>
  <rect x="380" y="70" width="140" height="64" rx="6" fill="#e2e8f0"/>
  <text x="450" y="106" text-anchor="middle" font-size="12" font-weight="700" fill="#334155">检测 crash / hang</text>
  <line x1="520" y1="102" x2="556" y2="102" stroke="#475569" stroke-width="1.6" marker-end="url(#sk-arrow)"/>
  <rect x="560" y="70" width="140" height="64" rx="6" fill="#e2e8f0"/>
  <text x="630" y="98" text-anchor="middle" font-size="12" font-weight="700" fill="#334155">复现 + 报告</text>
  <text x="630" y="116" text-anchor="middle" font-size="10" fill="#475569">(自动 bisect)</text>
  <line x1="630" y1="134" x2="630" y2="160" stroke="#475569" stroke-width="1.6" marker-end="url(#sk-arrow)"/>
  <rect x="20" y="164" width="680" height="70" rx="8" fill="#dcfce7" stroke="#4ade80"/>
  <text x="36" y="192" font-size="13" font-weight="700" fill="#166534">已发现 5000+ 内核 bug —— 覆盖率引导的随机 syscall 序列持续在 QEMU 里挖掘 crash/hang</text>
  <text x="36" y="214" font-size="12" fill="#15803d">部署:github.com/google/syzkaller</text>
</svg>

## LTP (Linux Test Project)

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

## Fault Injection

```bash
# 故障注入框架: 模拟各种硬件/内存/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*
