# 機能設計書 76-mrdbコマンド

## 概要

本ドキュメントは、mrubyデバッガ（mrdb）コマンドの設計について記述する。ブレークポイント設定、ステップ実行、変数表示等のデバッグ機能を提供するコマンドラインデバッガである。

### 本機能の処理概要

mrdbコマンドは、mrubyプログラムのデバッグを支援するインタラクティブなデバッガである。VMのcode_fetch_hookを利用して命令実行ごとにフック処理を挿入し、ブレークポイントの検出、ステップ/ネクスト実行、変数の表示・評価等を行う。

**業務上の目的・背景**：mrubyスクリプトの開発時に、実行時の変数状態の確認、処理フローの追跡、バグの原因特定を効率的に行うためのデバッグツールが必要。GDBライクなコマンドインターフェースで親しみやすいデバッグ体験を提供する。

**機能の利用シーン**：スクリプトの実行時バグ調査、処理フローの確認、ブレークポイントを使った条件付き停止、ローカル変数の確認、式の評価。

**主要な処理内容**：
1. ブレークポイント管理（行ブレーク・メソッドブレーク）
2. 実行制御（run/continue/step/next）
3. 変数・式の表示（print/eval/info locals）
4. ソースリスト表示（list）
5. code_fetch_hookによる命令レベルのフック

**関連システム・外部連携**：mruby-evalに依存（eval/printコマンドで使用）。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | コマンドラインデバッガ。画面なし |

## 機能種別

デバッガ / コマンドラインツール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -b | フラグ | No | RiteBinary（.mrb）ファイルとして読み込み | - |
| -d path | 文字列 | No | ソースディレクトリ指定（複数指定可） | - |
| --version | フラグ | No | バージョン表示して終了 | - |
| --copyright | フラグ | No | 著作権表示して終了 | - |
| programfile | 文字列 | Yes | デバッグ対象プログラムファイル | - |

### デバッガコマンド

| コマンド | 短縮形 | 説明 |
|---------|--------|------|
| break [file:]line/method | b | ブレークポイント設定 |
| continue | c | 実行再開 |
| delete [bpno] | d | ブレークポイント削除 |
| disable [bpno] | dis | ブレークポイント無効化 |
| enable [bpno] | en | ブレークポイント有効化 |
| eval expr | ev | 式の評価 |
| help | h | ヘルプ表示 |
| info breakpoints | i b | ブレークポイント一覧 |
| info locals | i l | ローカル変数一覧 |
| list | l | ソースリスト表示 |
| print expr | p | 式の評価・表示 |
| quit | q | デバッガ終了 |
| run | r | プログラム実行開始 |
| step [n] | s | ステップ実行 |
| next [n] | n | ネクスト実行（関数内に入らない） |

### 入力データソース

- コマンドライン引数
- 対話入力（デバッガコマンド）
- Rubyソース/バイナリファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ブレークポイント情報 | テキスト | 停止位置のファイル名・行番号 |
| 変数値 | テキスト | print/eval結果 |
| ソースリスト | テキスト | ソースコードの該当範囲 |
| プロンプト | テキスト | "(file:line) "形式 |

### 出力先

標準出力。

## 処理フロー

### 処理シーケンス

```
1. mrb_open() でVM初期化
2. parse_args() で引数解析
3. デバッグコンテキスト初期化
4. code_fetch_hookとbreak_hookの設定
5. プログラム読み込み・実行
   └─ 各命令実行前にcode_fetch_hookが呼ばれる
      ├─ DBG_INIT: 初期停止
      ├─ DBG_RUN: ブレークポイント検査
      ├─ DBG_STEP: 行変更で停止
      └─ DBG_NEXT: 同レベル行変更で停止
6. 停止時: break_hookが呼ばれる
   ├─ 停止情報表示
   ├─ コマンド入力待ち
   └─ コマンド実行
7. プログラム終了後もコマンド入力可能
8. quitでデバッガ終了
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[VM初期化]
    B --> C[デバッグコンテキスト初期化]
    C --> D[hook設定]
    D --> E[プログラム実行開始]
    E --> F[code_fetch_hook]
    F --> G{実行モード}
    G -->|DBG_INIT| H[初期停止]
    G -->|DBG_RUN| I{ブレークポイント?}
    G -->|DBG_STEP| J{行変更?}
    G -->|DBG_NEXT| K{同レベル行変更?}
    I -->|Yes| L[break_hook]
    I -->|No| M[次の命令へ]
    J -->|Yes| L
    J -->|No| M
    K -->|Yes| L
    K -->|No| M
    H --> L
    L --> N[コマンド入力]
    N --> O{コマンド種別}
    O -->|continue| M
    O -->|step| P[DBG_STEP設定→次命令]
    O -->|quit| Q[終了]
    M --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-76-1 | 行ブレークポイント | ファイル名と行番号でブレークポイントを設定 | breakコマンド |
| BR-76-2 | メソッドブレークポイント | クラス名:メソッド名でブレークポイントを設定 | breakコマンド |
| BR-76-3 | step実行 | 次の行に進む（関数内にも入る） | stepコマンド |
| BR-76-4 | next実行 | 次の行に進む（関数呼び出しはスキップ） | nextコマンド（ciレベル比較） |
| BR-76-5 | C関数ブレーク | C関数へのメソッドブレーク時は呼び出し前に停止 | isCfunc=TRUE時 |
| BR-76-6 | リスタート | DebuggerRestart例外でプログラムを再実行 | runコマンド |

### 計算ロジック

特になし。

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| EXIT_FAILURE | ファイルオープン失敗 | プログラムファイルが開けない | エラーメッセージ表示 |
| EXIT_FAILURE | ファイル未指定 | programfileが未指定 | "Program file not specified" |
| - | 無効コマンド | 不明なデバッガコマンド | "invalid command"表示 |

### リトライ仕様

デバッガのため、エラー後もコマンド入力を続行可能。

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

該当なし。

## パフォーマンス要件

- code_fetch_hookは各命令実行前に呼ばれるため、デバッグ時はオーバーヘッドが発生する
- MAX_BREAKPOINT（mrdbconf.hで定義）がブレークポイント上限

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

- eval/printコマンドで任意のRubyコードを実行可能

## 備考

- mruby-evalに依存（eval/printコマンドの実装で必要）
- MAX_COMMAND_LINE（mrdbconf.hで定義）がコマンド入力の最大長
- DebuggerExit/DebuggerRestart例外で終了/再起動を制御

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mrdb.h | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h` | mrb_debug_context構造体（97-124行目） |
| 1-2 | mrdb.h | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h` | mrdb_state構造体（126-135行目） |
| 1-3 | mrdb.h | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h` | 列挙型定義（15-75行目） |
| 1-4 | mrdb.h | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h` | mrb_debug_breakpoint構造体（87-95行目） |

**読解のコツ**: mrb_debug_contextはVMフックから参照される中核データ。xm（実行モード: INIT/RUN/STEP/NEXT/QUIT）、bm（停止理由: BREAK/STEP/NEXT）、xphase（実行フェーズ）の3つの状態変数がデバッガの動作を制御する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | mrdb.c | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c` | main関数（662-768行目） |

**主要処理フロー**:
1. **665行目**: mrb_openでVM初期化
2. **683行目**: parse_argsで引数解析
3. **691行目**: mrdb_state_getでデバッグ状態初期化
4. **705-706行目**: code_fetch_hookとbreak_hookの設定
5. **708-716行目**: プログラム読み込み実行（.mrb/.rb分岐）
6. **717-738行目**: DebuggerExit/DebuggerRestart例外処理

#### Step 3: code_fetch_hookの動作を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | mrdb.c | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c` | mrb_code_fetch_hook関数（551-638行目） |

**主要処理フロー**:
- **578-586行目**: DBG_STEP: 行変更時に停止
- **587-597行目**: DBG_NEXT: 同レベル以下の行変更時に停止（ciレベル比較）
- **599-616行目**: DBG_RUN: メソッドブレーク・行ブレークの検査
- **635行目**: break_hookコールバック呼び出し

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mrdb.c | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c` | debug_command_list（47-64行目） |
| 4-2 | mrdb.c | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c` | parse_command関数（325-400行目） |
| 4-3 | mrdb.c | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c` | mrb_debug_break_hook関数（640-660行目） |

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

```
main
    ├─ mrb_open
    ├─ parse_args
    ├─ mrdb_state_get → mrdb_state_new
    ├─ mrb_debug_context_get → mrb_debug_context_new
    ├─ mrb_load_irep_file / mrb_load_file_cxt
    │   └─ [各命令実行時]
    │       └─ mrb_code_fetch_hook
    │           ├─ check_method_breakpoint
    │           ├─ mrb_debug_check_breakpoint_line
    │           └─ break_hook (停止時)
    │               └─ mrb_debug_break_hook
    │                   ├─ print_info_stopped
    │                   └─ get_and_parse_command (ループ)
    │                       ├─ get_command
    │                       ├─ parse_command
    │                       └─ cmd->func (コマンド実行)
    └─ cleanup
```

### データフロー図

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

プログラム ──────▶ VM実行 ──────────────▶ 通常実行
                     │
              code_fetch_hook
                     │
              ブレーク判定 ──────────▶ 停止情報表示
                     │
デバッガコマンド ──▶ parse_command ────▶ コマンド実行
                     │                       │
                     ▼                       ▼
              break/continue/step ──▶ 実行モード変更
              print/eval ──────────▶ 式評価結果表示
              info locals ─────────▶ 変数一覧表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mrdb.c | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c` | ソース | メインデバッガロジック |
| mrdb.h | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.h` | ヘッダ | データ構造・API定義 |
| mrdbconf.h | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdbconf.h` | ヘッダ | 設定定数 |
| mrdberror.h | `mrbgems/mruby-bin-debugger/tools/mrdb/mrdberror.h` | ヘッダ | エラー定義 |
| cmdrun.c | `mrbgems/mruby-bin-debugger/tools/mrdb/cmdrun.c` | ソース | run/continue/step/nextコマンド |
| cmdbreak.c | `mrbgems/mruby-bin-debugger/tools/mrdb/cmdbreak.c` | ソース | ブレークポイント関連コマンド |
| cmdprint.c | `mrbgems/mruby-bin-debugger/tools/mrdb/cmdprint.c` | ソース | print/evalコマンド |
| cmdmisc.c | `mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c` | ソース | list/help/quitコマンド |
| apibreak.c/h | `mrbgems/mruby-bin-debugger/tools/mrdb/apibreak.c` | ソース | ブレークポイントAPI |
| apilist.c/h | `mrbgems/mruby-bin-debugger/tools/mrdb/apilist.c` | ソース | ソースリストAPI |
| apiprint.c/h | `mrbgems/mruby-bin-debugger/tools/mrdb/apiprint.c` | ソース | 出力API |
| apistring.c/h | `mrbgems/mruby-bin-debugger/tools/mrdb/apistring.c` | ソース | 文字列操作API |
| mrbgem.rake | `mrbgems/mruby-bin-debugger/mrbgem.rake` | 設定 | gem定義 |
