# 通知設計書 56-NOTIFICATION_CRASH

## 概要

本ドキュメントは、Godotエンジンにおけるクラッシュ発生時に発火するNOTIFICATION_CRASH通知の設計仕様を定義する。

### 本通知の処理概要

NOTIFICATION_CRASHは、Godotエンジンのクラッシュハンドラがエンジンのクラッシュを検知した際に発火する緊急システム通知である。この通知により、クラッシュ前の最後の機会として、重要なデータの保存やクラッシュ情報のログ記録などを実行することができる。

**業務上の目的・背景**：アプリケーションの予期せぬクラッシュ時に、ユーザーデータの損失を最小限に抑えるための最後の機会を提供する。ゲームの進行状況の自動保存、エディタでの未保存変更の緊急バックアップ、クラッシュレポートの収集などに活用できる。デスクトッププラットフォーム（Windows、macOS、Linux）でクラッシュハンドラが有効な場合にのみ実装されている。

**通知の送信タイミング**：シグナルハンドラ（SIGSEGV、SIGFPE、SIGBUS、SIGILL等）が発火した時点、またはSEH（Windows構造化例外処理）がクラッシュを検知した時点で発火する。

**通知の受信者**：SceneTreeのルートノードから全ての子ノードに対して`propagate_notification`を通じて伝播される。

**通知内容の概要**：通知値2012を持つ整数通知として送信される。追加のパラメータは含まれない。

**期待されるアクション**：受信者は可能な限り高速に重要データの保存処理を実行することが期待される。ただし、クラッシュ状態では正常な動作が保証されないため、処理は最小限に留めるべきである。

## 通知種別

エンジン内部通知（Object._notification経由）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（緊急） |
| 優先度 | 最高（クリティカル） |
| リトライ | なし |

### 送信先決定ロジック

クラッシュハンドラからMainLoop::notification()を通じて発火し、SceneTree経由でルートノードから全ての子ノードに伝播される。

## 通知テンプレート

### 通知定数定義

| 項目 | 内容 |
|-----|------|
| 定数名 | NOTIFICATION_CRASH |
| 値 | 2012 |
| 定義場所 | core/os/main_loop.h（Nodeで再定義） |

### 受信処理例

```gdscript
func _notification(what):
    if what == NOTIFICATION_CRASH:
        # 緊急保存処理（最小限の処理のみ）
        _emergency_save_game_data()
        print("Emergency save completed before crash")

func _emergency_save_game_data():
    # 重要なデータのみを保存
    var save_file = FileAccess.open("user://emergency_save.dat", FileAccess.WRITE)
    if save_file:
        save_file.store_var(player_data)
        save_file.close()
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| なし | 追加パラメータなし | - | - |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| シグナル | SIGSEGV | セグメンテーション違反 | メモリアクセス違反 |
| シグナル | SIGFPE | 浮動小数点例外 | 0除算など |
| シグナル | SIGBUS | バスエラー | アライメント違反など |
| シグナル | SIGILL | 不正命令 | CPUが実行できない命令 |
| SEH（Windows） | EXCEPTION_ACCESS_VIOLATION | アクセス違反 | Windows固有 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| クラッシュハンドラ無効 | コンパイル時にクラッシュハンドラが無効化されている場合 |
| SceneTree未初期化 | ルートノードが存在しない場合 |
| 再帰クラッシュ | クラッシュ処理中に再度クラッシュした場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[クラッシュ発生] --> B[OSシグナル/SEH検知]
    B --> C[CrashHandler起動]
    C --> D{MainLoop存在?}
    D -->|Yes| E[MainLoop::notification発火]
    E --> F[SceneTree::_notification]
    F --> G{ルートノード存在?}
    G -->|Yes| H[get_root->propagate_notification]
    H --> I[全ノードへ通知伝播]
    I --> J[緊急保存処理実行]
    J --> K[クラッシュダンプ生成]
    K --> L[プロセス終了]
    D -->|No| K
    G -->|No| K
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（データベースを使用しない内部通知）

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 再帰クラッシュ | 通知処理中に再度クラッシュ | 即座にプロセス終了 |
| 保存失敗 | ファイルI/Oエラー | ログ出力して継続 |
| タイムアウト | 処理時間超過 | OSによる強制終了 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 1回（クラッシュは1回のみ） |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし（クラッシュ発生時に随時発火）

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

- クラッシュダンプには機密情報が含まれる可能性がある
- 緊急保存データは暗号化されない場合がある
- クラッシュレポート送信時はユーザー同意が必要

## 備考

- デスクトッププラットフォーム（Windows、macOS、Linux）でクラッシュハンドラが有効な場合にのみ実装
- クラッシュ状態では正常な動作が保証されないため、処理は最小限に留めること
- Windowsではsignal方式とSEH方式の2つの実装が存在する
- この通知の処理中は追加のエラーが発生しやすいため、try-catchの使用を推奨

---

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

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

### 推奨読解順序

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

通知の定数値とその定義場所を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | main_loop.h | `core/os/main_loop.h` | NOTIFICATION_CRASH = 2012 の定義（53行目） |
| 1-2 | node.h | `scene/main/node.h` | Nodeクラスでの再定義（492行目） |

**読解のコツ**: MainLoopで定義された通知定数がNodeクラスで再定義されていることを確認する。

#### Step 2: プラットフォーム固有のクラッシュハンドラを理解する

各プラットフォームのクラッシュハンドラ実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | crash_handler_linuxbsd.cpp | `platform/linuxbsd/crash_handler_linuxbsd.cpp` | Linux/BSD用クラッシュハンドラ |
| 2-2 | crash_handler_macos.mm | `platform/macos/crash_handler_macos.mm` | macOS用クラッシュハンドラ |
| 2-3 | crash_handler_windows_seh.cpp | `platform/windows/crash_handler_windows_seh.cpp` | Windows SEH方式 |
| 2-4 | crash_handler_windows_signal.cpp | `platform/windows/crash_handler_windows_signal.cpp` | Windows signal方式 |

**主要処理フロー**:
1. シグナルハンドラまたはSEHハンドラの登録
2. クラッシュシグナル受信
3. MainLoop::notification(NOTIFICATION_CRASH)の呼び出し
4. クラッシュダンプの生成

#### Step 3: 通知伝播処理を理解する

SceneTreeでの通知処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | scene_tree.cpp | `scene/main/scene_tree.cpp` | _notification()メソッドでのNOTIFICATION_CRASH処理（914行目） |

**主要処理フロー**:
1. **914行目**: `case NOTIFICATION_CRASH:` - クラッシュケースの判定
2. **920行目**: `get_root()->propagate_notification(p_notification)` - ルートから全ノードへ伝播

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

```
OS Signal/SEH
    │
    ├─ [Linux/BSD] crash_handler_linuxbsd.cpp::handle_crash()
    │
    ├─ [macOS] crash_handler_macos.mm::handle_crash()
    │
    ├─ [Windows] crash_handler_windows_*.cpp::handle_crash()
    │
    └─ MainLoop::notification(NOTIFICATION_CRASH)
           │
           └─ SceneTree::_notification()
                  │
                  └─ get_root()->propagate_notification()
                         │
                         └─ Node::_notification() [再帰的に伝播]
                                │
                                └─ 緊急保存処理
```

### データフロー図

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

クラッシュ      CrashHandler           MainLoop通知
シグナル   ───▶  起動         ───▶      発火
                      │
                      ▼
                SceneTree
              _notification()
                      │
                      ▼
              全ノードへ伝播
                      │
                      ├───▶ 緊急保存処理
                      │
                      └───▶ クラッシュダンプ生成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main_loop.h | `core/os/main_loop.h` | ソース | 通知定数の定義 |
| main_loop.cpp | `core/os/main_loop.cpp` | ソース | MainLoopの通知バインド |
| node.h | `scene/main/node.h` | ソース | Nodeクラスでの通知定数再定義 |
| scene_tree.cpp | `scene/main/scene_tree.cpp` | ソース | 通知の伝播処理 |
| crash_handler_linuxbsd.cpp | `platform/linuxbsd/crash_handler_linuxbsd.cpp` | ソース | Linux/BSD用クラッシュハンドラ |
| crash_handler_macos.mm | `platform/macos/crash_handler_macos.mm` | ソース | macOS用クラッシュハンドラ |
| crash_handler_windows_seh.cpp | `platform/windows/crash_handler_windows_seh.cpp` | ソース | Windows SEH方式クラッシュハンドラ |
| crash_handler_windows_signal.cpp | `platform/windows/crash_handler_windows_signal.cpp` | ソース | Windows signal方式クラッシュハンドラ |
| MainLoop.xml | `doc/classes/MainLoop.xml` | ドキュメント | 通知の公式ドキュメント |
