# 機能設計書 9-DDB カーネルデバッガ

## 概要

本ドキュメントは、FreeBSDにおけるDDB（Debugger for DB: in-kernel DeBugger）カーネルデバッガ機能の設計を記述する。カーネル内蔵のインタラクティブデバッガを対象とする。

### 本機能の処理概要

**業務上の目的・背景**：DDBはFreeBSDカーネルに内蔵されたインタラクティブデバッガであり、カーネルパニック時やブレークポイント到達時にカーネルの内部状態を調査できる。リモートデバッガ（GDB）が利用できない環境やカーネルクラッシュの初期調査に不可欠なツールである。元々はMachオペレーティングシステム由来のデバッガである。

**機能の利用シーン**：カーネルパニック時の原因調査、カーネルブレークポイントの設定、メモリ内容の表示・変更、スタックトレースの取得、プロセス一覧の表示、カーネルシンボルの検索、CTF（Compact Type Format）を利用した型情報の表示で利用される。

**主要な処理内容**：
1. **デバッガエントリ**: カーネルパニック、ブレークポイント、NMI、コンソールからのCtrl+Alt+ESC等でDDBに入る。
2. **コマンド処理**: db_command.cによるインタラクティブコマンドの解析・実行。examine（メモリ表示）、trace（スタックトレース）、show（各種情報表示）、break（ブレークポイント）等。
3. **シンボル解決**: db_sym.cによるカーネルシンボルテーブルの検索。アドレスからシンボル名、シンボル名からアドレスへの双方向解決。
4. **メモリ表示・変更**: db_examine.cによるメモリ内容の表示。各種フォーマット（16進、10進、文字列等）でのダンプ。
5. **CTF情報表示**: db_ctf.cによるCTFデータの参照。構造体フィールドの型情報に基づくpretty print。
6. **キャプチャ機能**: db_capture.cによるDDBセッションの出力キャプチャ。後でsysctlやddbコマンドで取得可能。

**関連システム・外部連携**：KDB（Kernel Debugger Backend）フレームワーク（sys/kdb.h）、コンソールドライバ、linkerサブシステム（シンボル情報）、savecore（クラッシュダンプ保存）。

**権限による制御**：DDBへのエントリは通常カーネルモードのイベント（パニック等）で発生し、物理コンソールアクセスが必要。sbin/ddbコマンドでの設定にはroot権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | DDBはコンソールベースのインタラクティブデバッガであり、GUI画面は存在しない |

## 機能種別

カーネル基盤機能（カーネルデバッグ・診断）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| DDBコマンド | char * | Yes | デバッガコマンド（examine, trace等） | コマンドテーブルに存在 |
| アドレス式 | 式 | No | メモリアドレスまたはシンボル名 | 有効なアドレス範囲 |
| /フォーマット | char | No | 表示フォーマット（x:16進, d:10進等） | 有効なフォーマット文字 |

### 入力データソース

物理コンソールからのキーボード入力、sbin/ddbコマンドによるスクリプト設定。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| メモリダンプ | テキスト | 指定アドレスのメモリ内容 |
| スタックトレース | テキスト | カーネルスタックのバックトレース |
| プロセス一覧 | テキスト | 現在のプロセス/スレッド一覧 |
| シンボル情報 | テキスト | アドレスに対応するシンボル名 |

### 出力先

物理コンソール出力、キャプチャバッファ（db_capture.c）。

## 処理フロー

### 処理シーケンス

```
1. DDBエントリ
   ├─ カーネルパニック / ブレークポイント / NMI
   │    ├─ kdb_enter(): KDBフレームワーク経由
   │    ├─ db_trap(): DDBトラップハンドラ
   │    └─ db_command_loop(): コマンドループ開始

2. コマンド実行
   ├─ db_read_line(): コンソールからコマンド読み取り
   │    ├─ db_lex(): 字句解析
   │    ├─ db_command(): コマンド検索・実行
   │    └─ 各コマンドハンドラ実行

3. DDBリターン
   └─ continue / reboot / panic コマンドでDDBを抜ける
```

### フローチャート

```mermaid
flowchart TD
    A[カーネルパニック/ブレークポイント] --> B[kdb_enter]
    B --> C[db_trap: DDBエントリ]
    C --> D[db_command_loop]
    D --> E[db_read_line: コマンド入力]
    E --> F[db_lex: 字句解析]
    F --> G[db_command: コマンド実行]
    G --> H{continue?}
    H -->|No| E
    H -->|Yes| I[カーネル実行再開]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | パニック時自動エントリ | debug.debugger_on_panic sysctl有効時にパニックでDDBに入る | デフォルト有効 |
| BR-02 | 全CPU停止 | DDBエントリ時に全CPUを停止 | SMPシステム |
| BR-03 | コンソールアクセス必須 | DDBは物理コンソールからのみ操作可能 | 全DDB操作時 |
| BR-04 | キャプチャ保存 | DDBセッション出力をキャプチャバッファに保存可能 | db_capture有効時 |

### 計算ロジック

シンボル解決はlinkerファイルのシンボルテーブルを二分探索し、最も近いシンボルとオフセットを返す。CTF情報の解析はdb_ctf.cで実装され、構造体メンバのオフセット・型情報を提供する。

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデバッグ専用であり、永続的なデータベース操作は行わない。

| 操作 | 対象データ構造 | 操作種別 | 概要 |
|-----|-------------|---------|------|
| examine | カーネルメモリ | SELECT | メモリ内容の読み取り |
| write | カーネルメモリ | UPDATE | メモリ内容の変更（デバッグ用） |
| break | ブレークポイントリスト | INSERT/DELETE | ブレークポイントの設定・解除 |

### テーブル別操作詳細

該当なし（カーネルメモリの直接操作）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 不正アドレス | 無効なメモリアドレスの参照 | 有効なアドレスを指定 |
| - | コマンド不明 | 存在しないコマンドの入力 | helpコマンドで確認 |
| - | シンボル不明 | 存在しないシンボル名の指定 | 正しいシンボル名を使用 |

### リトライ仕様

DDB内でのエラーはコマンドループ内で処理され、エラーメッセージ表示後に次のコマンド入力を待つ。DDB自体がクラッシュした場合はdouble panicとなる。

## トランザクション仕様

DDB実行中は全CPUが停止しており、排他制御の必要はない。ただしDDBのメモリ変更操作はアトミックではなく、デバッグ用途に限定される。

## パフォーマンス要件

DDBはデバッグ専用であり、性能要件は特にない。DDBエントリ中はシステム全体が停止するため、デバッグ完了後は速やかにcontinueまたはrebootを実行すべき。

## セキュリティ考慮事項

- 物理コンソールアクセスが必要（リモートからの不正アクセスは不可）
- DDBからカーネルメモリの読み書きが可能なため、物理的なセキュリティが重要
- debug.ddb.from_consoleフラグでコンソールからのDDBエントリを制御可能

## 備考

- DDBはMachオペレーティングシステム由来（db_main.cの1-27行目のCMU著作権表記）
- db_main.cの48-52行目でstruct db_private構造体が定義され、シンボルテーブルの管理に使用
- db_main.cの56-57行目でdebug.ddb sysctlノードが登録されている
- sbin/ddbコマンドでDDBの動作設定（パニック時の自動スクリプト実行等）が可能

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ddb.h | `sys/ddb/ddb.h` | DDBの公開インタフェース定義 |
| 1-2 | db_command.h | `sys/ddb/db_command.h` | コマンドテーブル構造体の定義 |

**読解のコツ**: DDBのコマンドは`struct db_command`構造体の配列（コマンドテーブル）で管理されている。各コマンドは名前、関数ポインタ、フラグの組で定義される。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | db_main.c | `sys/ddb/db_main.c` | db_init()（59行目）とdb_trap()（60行目）がDDBバックエンドの初期化・トラップハンドラ |

**主要処理フロー**:
1. **48-52行目**: struct db_privateの定義（strtab、relbase）
2. **56-57行目**: debug.ddb sysctlノードの登録
3. **59行目**: db_init関数（dbbe_init_f型）
4. **60行目**: db_trap関数（dbbe_trap_f型）

#### Step 3: コマンド処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | db_command.c | `sys/ddb/db_command.c` | コマンドテーブルの定義と検索。db_command_loop()が主要ループ |
| 3-2 | db_input.c | `sys/ddb/db_input.c` | コンソールからの入力処理 |
| 3-3 | db_lex.c | `sys/ddb/db_lex.c` | 字句解析器 |

#### Step 4: 各機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | db_examine.c | `sys/ddb/db_examine.c` | メモリ表示（examine/x/print）コマンド |
| 4-2 | db_break.c | `sys/ddb/db_break.c` | ブレークポイント管理 |
| 4-3 | db_ps.c | `sys/ddb/db_ps.c` | プロセス一覧表示 |
| 4-4 | db_ctf.c | `sys/ddb/db_ctf.c` | CTF型情報表示 |
| 4-5 | db_capture.c | `sys/ddb/db_capture.c` | セッション出力キャプチャ |

### プログラム呼び出し階層図

```
kdb_enter() [KDBフレームワーク]
    |
    +-- db_trap() [DDBトラップハンドラ]
            |
            +-- db_command_loop()
                    |
                    +-- db_read_line() [入力読取]
                    +-- db_lex() [字句解析]
                    +-- db_command() [コマンド実行]
                            |
                            +-- db_examine() [メモリ表示]
                            +-- db_trace_thread() [スタックトレース]
                            +-- db_show_all_procs() [プロセス一覧]
                            +-- db_break_cmd() [ブレークポイント]
                            +-- db_pprint_cmd() [CTF pretty print]
```

### データフロー図

```
[入力]                  [処理]                         [出力]

パニック/NMI ────> kdb_enter() → db_trap() ────────> DDBプロンプト

コマンド文字列 ──> db_lex() → db_command() ────────> コマンド結果
                                                       コンソール出力

アドレス式 ──────> db_examine() ────────────────────> メモリダンプ
                   db_sym.c [シンボル解決]              シンボル名表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| db_main.c | `sys/ddb/db_main.c` | ソース | DDBメイン初期化・トラップ |
| db_command.c | `sys/ddb/db_command.c` | ソース | コマンドテーブル・実行ループ |
| db_examine.c | `sys/ddb/db_examine.c` | ソース | メモリ表示コマンド |
| db_break.c | `sys/ddb/db_break.c` | ソース | ブレークポイント管理 |
| db_sym.c | `sys/ddb/db_sym.c` | ソース | シンボル解決 |
| db_ctf.c | `sys/ddb/db_ctf.c` | ソース | CTF型情報表示 |
| db_capture.c | `sys/ddb/db_capture.c` | ソース | セッションキャプチャ |
| db_input.c | `sys/ddb/db_input.c` | ソース | コンソール入力処理 |
| db_lex.c | `sys/ddb/db_lex.c` | ソース | 字句解析器 |
| db_output.c | `sys/ddb/db_output.c` | ソース | 出力フォーマッタ |
| db_print.c | `sys/ddb/db_print.c` | ソース | 各種print処理 |
| db_ps.c | `sys/ddb/db_ps.c` | ソース | プロセス一覧表示 |
| db_expr.c | `sys/ddb/db_expr.c` | ソース | 式評価器 |
| db_pprint.c | `sys/ddb/db_pprint.c` | ソース | pretty print |
| db_access.c | `sys/ddb/db_access.c` | ソース | メモリアクセス |
| ddb.h | `sys/ddb/ddb.h` | ヘッダ | DDB公開インタフェース |
| db_command.h | `sys/ddb/db_command.h` | ヘッダ | コマンド構造体定義 |
