---
title: デバッグとテスト
url: https://doc.liz6.com/ja/linux-kernel/11-kernel-development-and-build/02-debugging-and-testing
locale: ja
area: linux-kernel
tags:
- linux-kernel
- kernel-development-and-build
date: 2026-06-30
modified: 2026-07-16
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.5 以降の構造化ログ: dev_printk, pr_fmt
```

## Dynamic Debug

```bash
# モジュール/関数/ファイル/行番号ごとにデバッグログを有効化 (ランタイム、再コンパイル不要)
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=関数名を含める, l=行番号を含める, t=スレッドIDを含める

# 有効化されたエントリを確認
cat /sys/kernel/debug/dynamic_debug/control | grep "=p"
```

## KGDB: カーネルレベルの GDB

```bash
# シリアル経由でカーネルをリモートデバッグ (gdbserver に類似)
# ブート引数: 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 シーケンスの生成からカーネルバグの発見まで">
  <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: カバレッジ誘導の自律型カーネルファザー</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">クラッシュ/ハングを検出</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">(自動バイセクト)</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 以上のカーネルバグを発見 —— カバレッジ誘導によるランダムな syscall シーケンスが QEMU 内で継続的にクラッシュ/ハングを掘り起こす</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 ごとに 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*
