# 機能設計書 112-デバッガー

## 概要

本ドキュメントは、BunのJavaScriptデバッガー機能の設計を記述する。WebKit Inspector Protocolに対応し、VSCodeやブラウザベースのデバッガー（debug.bun.sh）との連携を可能にする。

### 本機能の処理概要

Bunのデバッガーは、JavaScriptCore（WebKit）のInspectorフレームワークを活用し、JavaScriptコードのステップ実行、ブレークポイント設定、変数検査などのデバッグ機能を提供する。別スレッドでデバッガーサーバーを起動し、WebSocket経由でデバッグクライアント（IDE、ブラウザ）と通信する。

**業務上の目的・背景**：JavaScript開発において、デバッガーは不可欠なツールである。Bunは高速なランタイムを提供するが、開発時にはコードの動作を詳細に追跡する必要がある。標準的なInspectorプロトコルをサポートすることで、開発者は既存のデバッグツール（VSCode、Chrome DevTools等）をそのまま使用できる。

**機能の利用シーン**：
- `--inspect`フラグでのデバッグセッション開始
- `--inspect-wait`フラグでの接続待機付きデバッグ
- `--inspect-brk`フラグでの最初の行でブレーク
- VSCode拡張機能からの接続
- debug.bun.shブラウザデバッガーからの接続
- テスト実行時のテスト結果レポート（TestReporterAgent）
- ライフサイクルイベント通知（LifecycleAgent）

**主要な処理内容**：
1. デバッガーVMの作成と専用スレッドでの起動
2. WebSocket/UNIXソケットでのデバッグクライアント接続待機
3. JavaScriptCoreのInspectorとの連携
4. 非同期タスクの追跡（AsyncTaskTracker）
5. テスト結果のリアルタイムレポート
6. リロード・エラーイベントの通知

**関連システム・外部連携**：
- JavaScriptCore Inspector
- WebKit Inspector Protocol
- VSCode Bun拡張機能
- debug.bun.sh（ブラウザベースデバッガー）
- Bunテストランナー

**権限による制御**：特になし（デバッグフラグ有効時のみ動作）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はランタイム内部機能であり、外部デバッガーUIと連携 |

## 機能種別

デバッグ支援 / プロセス間通信 / イベント通知

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path_or_port | ?[]const u8 | No | デバッガー接続先（ポート番号またはUNIXソケットパス） | - |
| from_environment_variable | []const u8 | No | BUN_INSPECT環境変数からの設定値 | - |
| wait_for_connection | Wait | No | 接続待機モード（off/shortly/forever） | - |
| set_breakpoint_on_first_line | bool | No | 最初の行でブレークするか | - |
| mode | enum{listen, connect} | No | 接続モード（サーバー/クライアント） | - |

### 入力データソース

- コマンドライン引数（--inspect, --inspect-wait, --inspect-brk）
- BUN_INSPECT環境変数
- VirtualMachine設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| script_execution_context_id | u32 | デバッガーコンテキストID |
| next_debugger_id | u64 | 次のデバッガーセッションID |
| AsyncTaskTracker | struct | 非同期タスク追跡情報 |
| TestReporterAgent出力 | - | テスト発見・開始・終了イベント |
| LifecycleAgent出力 | - | リロード・エラーイベント |

### 出力先

- WebSocket経由でデバッグクライアントへ
- UNIXソケット経由でデバッグクライアントへ
- コンソール（デバッグログ）

## 処理フロー

### 処理シーケンス

```
1. デバッガー作成（create）
   └─ Bun__createJSDebugger呼び出し
   └─ script_execution_context_id取得
   └─ 専用スレッドでデバッガーサーバー起動

2. 接続待機（waitForDebuggerIfNecessary）
   └─ Futexによるブロック待機
   └─ イベントループのtick実行
   └─ タイムアウト処理（shortlyモード：30ms）

3. デバッガースレッド起動（startJSDebuggerThread）
   └─ MimallocArenaによるスレッドローカルヒープ作成
   └─ 専用VirtualMachine作成
   └─ Bun__startJSDebuggerThread呼び出し

4. 接続完了通知（Debugger__didConnect）
   └─ wait_for_connectionをoffに設定
   └─ poll_refを解放
   └─ イベントループをwakeup

5. 非同期タスク追跡（AsyncTaskTracker）
   └─ didSchedule: タスクスケジュール通知
   └─ willDispatch: タスク実行開始通知
   └─ didDispatch: タスク実行完了通知
   └─ didCancel: タスクキャンセル通知
```

### フローチャート

```mermaid
flowchart TD
    A[デバッガー初期化要求] --> B{初回作成?}
    B -->|Yes| C[Bun__createJSDebugger]
    B -->|No| D[既存デバッガー使用]
    C --> E[専用スレッド起動]
    E --> F[デバッガーVM作成]
    F --> G{接続待機モード?}
    G -->|forever| H[クライアント接続まで待機]
    G -->|shortly| I[30msタイムアウト付き待機]
    G -->|off| J[待機なし]
    H --> K{接続完了?}
    I --> K
    K -->|Yes| L[Debugger__didConnect]
    K -->|No/Timeout| M[待機終了]
    L --> N[デバッグセッション開始]
    M --> N
    J --> N
    N --> O[イベントループ継続実行]
    O --> P{終了要求?}
    P -->|No| O
    P -->|Yes| Q[デバッガー終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 接続モード | listenモードではBunがサーバー、connectモードではクライアント | mode設定による |
| BR-002 | 待機タイムアウト | shortlyモードでは30ms待機後にタイムアウト | wait_for_connection=shortly |
| BR-003 | 最初の行ブレーク | set_breakpoint_on_first_line=trueで最初の行で停止 | --inspect-brk指定時 |
| BR-004 | テストレポート有効化 | TestReporterAgent.handleがnullでない場合のみレポート | デバッガー接続時 |
| BR-005 | 非同期タスクID | VirtualMachine.nextAsyncTaskID()で一意のID生成 | 非同期タスク追跡時 |
| BR-006 | 遡及レポート | デバッガー接続後に発見済みテストを遡及レポート | テスト収集/実行フェーズ |

### 計算ロジック

特になし

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | VM作成失敗 | デバッガーVM作成時のメモリ不足 | panic |
| - | 接続失敗 | デバッグクライアントへの接続失敗 | ログ出力、処理継続 |
| - | タイムアウト | shortly待機モードで30ms経過 | 待機終了、処理継続 |

### リトライ仕様

リトライは行わない。接続失敗時は処理を継続。

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

本機能はトランザクションを使用しない。

## パフォーマンス要件

- デバッガースレッドは専用スレッドで動作し、メインスレッドをブロックしない
- shortly待機モードでは最大30msの遅延
- 非同期タスク追跡はID=0の場合は即座にリターン（オーバーヘッド最小化）

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

- デバッガーはローカル接続のみを想定（リモートデバッグは要注意）
- BUN_INSPECT環境変数による設定は信頼された環境でのみ使用

## 備考

- Windowsではlibuv Timerを使用した待機処理
- デバッガースレッドは"Debugger"という名前で識別可能

---

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

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

### 推奨読解順序

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

デバッガーの設定と状態管理の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Debugger.zig | `src/bun.js/Debugger.zig` | Debugger構造体のフィールド定義 |

**読解のコツ**: Zigのopaque型とextern宣言は、JavaScriptCore（C++）との連携部分を示す。

**主要処理フロー**:
- **1-21行目**: Debugger設定フィールド（path_or_port, mode, wait_for_connection等）
- **22行目**: Wait列挙型（off, shortly, forever）
- **233-267行目**: AsyncTaskTracker構造体（非同期タスク追跡）
- **269-275行目**: AsyncCallType列挙型（DOMTimer, EventListener等）
- **298-456行目**: TestReporterAgent構造体（テストレポート）
- **458-517行目**: LifecycleAgent構造体（ライフサイクルイベント）

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

デバッガーの作成と起動処理を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Debugger.zig | `src/bun.js/Debugger.zig` | create, waitForDebuggerIfNecessary関数 |

**主要処理フロー**:
- **31-49行目**: waitForDebuggerIfNecessary - Futexによる接続待機
- **117-141行目**: create - デバッガー初回作成、スレッド起動
- **143-171行目**: startJSDebuggerThread - デバッガー専用スレッド処理

#### Step 3: 接続管理を理解する

デバッグクライアントとの接続管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Debugger.zig | `src/bun.js/Debugger.zig` | Debugger__didConnect, start関数 |

**主要処理フロー**:
- **173-180行目**: Debugger__didConnect - 接続完了時のコールバック（export）
- **182-231行目**: start - デバッガースレッドのメイン処理ループ

#### Step 4: 非同期タスク追跡を理解する

JavaScriptの非同期処理追跡機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Debugger.zig | `src/bun.js/Debugger.zig` | AsyncTaskTracker, didScheduleAsyncCall等 |

**主要処理フロー**:
- **236-238行目**: AsyncTaskTracker.init - タスクID取得
- **240-244行目**: didSchedule - タスクスケジュール通知
- **252-258行目**: willDispatch - タスク実行開始通知
- **260-266行目**: didDispatch - タスク実行完了通知
- **246-250行目**: didCancel - タスクキャンセル通知

#### Step 5: TestReporterAgentを理解する

テスト結果レポート機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | Debugger.zig | `src/bun.js/Debugger.zig` | TestReporterAgent構造体 |

**主要処理フロー**:
- **302-315行目**: TestStatus/TestType列挙型
- **317-338行目**: Handle opaque型とextern関数
- **339-347行目**: Bun__TestReporterAgentEnable - Agent有効化
- **351-422行目**: retroactivelyReportDiscoveredTests - 遡及レポート

#### Step 6: LifecycleAgentを理解する

ライフサイクルイベント通知機能を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | Debugger.zig | `src/bun.js/Debugger.zig` | LifecycleAgent構造体 |

**主要処理フロー**:
- **462-485行目**: Handle opaque型（reportReload, reportError等）
- **487-500行目**: Bun__LifecycleAgentEnable/Disable
- **502-516行目**: reportReload, reportError関数

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

```
VirtualMachine
    │
    └─ Debugger.create
           │
           ├─ Bun__createJSDebugger (C++ extern)
           │      └─ script_execution_context_id取得
           │
           └─ std.Thread.spawn(startJSDebuggerThread)
                  │
                  ├─ MimallocArena.init
                  │
                  ├─ VirtualMachine.init (デバッガー用)
                  │
                  └─ start
                         │
                         ├─ Bun__startJSDebuggerThread (C++ extern)
                         │
                         ├─ Futex.wake (メインスレッド起床)
                         │
                         └─ イベントループ (無限)

waitForDebuggerIfNecessary
    │
    ├─ Futex.waitForever (デバッガースレッド待ち)
    │
    ├─ Bun__ensureDebugger (C++ extern)
    │
    └─ イベントループtick (接続待ち)
           │
           └─ Debugger__didConnect (接続時)

AsyncTaskTracker
    │
    ├─ didScheduleAsyncCall → Debugger__didScheduleAsyncCall (C++)
    ├─ willDispatchAsyncCall → Debugger__willDispatchAsyncCall (C++)
    ├─ didDispatchAsyncCall → Debugger__didDispatchAsyncCall (C++)
    └─ didCancelAsyncCall → Debugger__didCancelAsyncCall (C++)

TestReporterAgent
    │
    ├─ reportTestFound → Bun__TestReporterAgentReportTestFound (C++)
    ├─ reportTestStart → Bun__TestReporterAgentReportTestStart (C++)
    └─ reportTestEnd → Bun__TestReporterAgentReportTestEnd (C++)
```

### データフロー図

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

コマンドライン引数  ───▶  Debugger初期化      ───▶  デバッガースレッド起動
  │                         │
  ├─ --inspect              ├─ create
  ├─ --inspect-wait         ├─ startJSDebuggerThread
  └─ --inspect-brk          └─ start
                                   │
                                   ▼
                            ┌─────────────────┐
                            │ WebSocket/      │ ◀──▶ デバッグクライアント
                            │ UNIXソケット    │       (VSCode, Chrome)
                            └─────────────────┘
                                   │
非同期タスク         ───▶   AsyncTaskTracker   ───▶  Inspector通知
  │                         │
  └─ setTimeout等           ├─ didSchedule
                            ├─ willDispatch
                            └─ didDispatch

テスト実行           ───▶   TestReporterAgent  ───▶  テスト結果通知
  │                         │
  └─ describe/test          ├─ reportTestFound
                            ├─ reportTestStart
                            └─ reportTestEnd
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Debugger.zig | `src/bun.js/Debugger.zig` | ソース | デバッガーメイン実装 |
| VirtualMachine.zig | `src/bun.js/VirtualMachine.zig` | ソース | VM管理（デバッガー保持） |
| InspectorBunFrontendDevServerAgent.zig | `src/bun.js/api/server/InspectorBunFrontendDevServerAgent.zig` | ソース | DevServerエージェント |
| HTTPServerAgent.zig | `src/bun.js/bindings/HTTPServerAgent.zig` | ソース | HTTPサーバーエージェント |
| jest.zig | `src/bun.js/test/jest.zig` | ソース | テストランナー連携 |
| Futex.zig | `src/Futex.zig` | ソース | スレッド同期 |
