303 lines
10 KiB
Markdown
303 lines
10 KiB
Markdown
|
|
# Phase 9.75-C DebugBox修正: 残存する39個のコンパイルエラー解決
|
|||
|
|
|
|||
|
|
**優先度**: 🔴 **緊急** (全開発ブロック中)
|
|||
|
|
**担当者**: @copilot-swe-agent
|
|||
|
|
**ステータス**: 未解決
|
|||
|
|
**作成日**: 2025-08-15
|
|||
|
|
**関連**: Issue #92 (解決済み), PR #93 (FutureBox修正完了)
|
|||
|
|
|
|||
|
|
## 🚨 問題概要
|
|||
|
|
|
|||
|
|
**Issue #92とPR #93でFutureBox問題は解決済み**ですが、**DebugBox**のArc<Mutex>→RwLock変換が完全に見落とされており、**39個のコンパイルエラー**が残存しています。
|
|||
|
|
|
|||
|
|
### 現在の状況
|
|||
|
|
```bash
|
|||
|
|
$ cargo check --lib
|
|||
|
|
error: could not compile `nyash-rust` (lib) due to 39 previous errors; 80 warnings emitted
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**影響**: 全開発がブロック - ビルド、テスト、Phase 9.5以降の作業継続不可
|
|||
|
|
|
|||
|
|
## 📋 現在の状況
|
|||
|
|
|
|||
|
|
### ✅ **解決済み問題** (Issue #92 / PR #93)
|
|||
|
|
- **FutureBox二重定義**: 完全解決
|
|||
|
|
- **10個のBox型**: HTTPServerBox、P2PBox等はRwLock変換済み
|
|||
|
|
|
|||
|
|
### ❌ **未解決問題** (この新しいIssue)
|
|||
|
|
- **DebugBox**: Arc<Mutex>→RwLock変換が完全に見落とされている
|
|||
|
|
|
|||
|
|
### ✅ 変換済みBox型 (PR #91 + PR #93)
|
|||
|
|
- **HTTPServerBox**: 7個のArc<Mutex>フィールド → RwLock
|
|||
|
|
- **P2PBox**: `Arc<Mutex<P2PBoxData>>`型エイリアスから完全書き換え
|
|||
|
|
- **IntentBox**: `Arc<Mutex<IntentBoxData>>`型エイリアスから完全書き換え
|
|||
|
|
- **SimpleIntentBox**: listenersハッシュマップ変換
|
|||
|
|
- **JSONBox**: serde_json::Value操作
|
|||
|
|
- **RandomBox**: seedフィールド変換
|
|||
|
|
- **EguiBox**: クロススレッドArc<RwLock>での複雑なGUI状態
|
|||
|
|
- **FileBox**: ファイルI/O操作、パス簡素化
|
|||
|
|
- **FutureBox**: 非同期状態管理 ✅ **PR #93で解決**
|
|||
|
|
- **SocketBox**: TCP操作更新
|
|||
|
|
|
|||
|
|
### ❌ **未変換Box型**
|
|||
|
|
- **DebugBox**: **完全に見落とされている**
|
|||
|
|
|
|||
|
|
## 🔍 DebugBox問題の技術的分析
|
|||
|
|
|
|||
|
|
**具体的エラー箇所**: `src/boxes/debug_box.rs`
|
|||
|
|
|
|||
|
|
### 📊 **特定されたエラー**
|
|||
|
|
|
|||
|
|
### 1. **DebugBox構造体**: Clone derive問題
|
|||
|
|
```rust
|
|||
|
|
// ❌ 現在の問題
|
|||
|
|
#[derive(Debug, Clone)] // RwLockはCloneを実装していない
|
|||
|
|
pub struct DebugBox {
|
|||
|
|
tracking_enabled: RwLock<bool>,
|
|||
|
|
tracked_boxes: RwLock<HashMap<String, TrackedBoxInfo>>,
|
|||
|
|
breakpoints: RwLock<Vec<String>>,
|
|||
|
|
call_stack: RwLock<Vec<CallInfo>>,
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. **11箇所の.lock()呼び出し**: メソッド名エラー
|
|||
|
|
```bash
|
|||
|
|
src/boxes/debug_box.rs:182 instance.fields.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:191 self.tracked_boxes.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:231 self.tracked_boxes.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:251 self.breakpoints.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:258 self.call_stack.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:274 self.call_stack.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:290 self.tracked_boxes.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:293 self.call_stack.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:306 self.tracked_boxes.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:322 self.tracked_boxes.lock().unwrap()
|
|||
|
|
src/boxes/debug_box.rs:345 self.tracked_boxes.lock().unwrap()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. **Clone実装**: 手動実装が必要
|
|||
|
|
RwLockはCloneを実装していないため、手動Clone実装が必要。
|
|||
|
|
|
|||
|
|
## 🎯 目標アーキテクチャ (達成すべき状態)
|
|||
|
|
```rust
|
|||
|
|
// ✅ 正しい: 単一責務設計
|
|||
|
|
struct DebugBox {
|
|||
|
|
tracking_enabled: RwLock<bool>, // シンプルな内部可変性
|
|||
|
|
tracked_boxes: RwLock<HashMap<String, TrackedBoxInfo>>,
|
|||
|
|
breakpoints: RwLock<Vec<String>>,
|
|||
|
|
call_stack: RwLock<Vec<CallInfo>>,
|
|||
|
|
}
|
|||
|
|
// 外部: Arc<Mutex<dyn NyashBox>> (変更なし)
|
|||
|
|
|
|||
|
|
// ❌ 間違い: 二重ロック問題 (排除済み)
|
|||
|
|
struct DebugBox {
|
|||
|
|
field: Arc<Mutex<T>>, // 内部ロック - 排除済み
|
|||
|
|
}
|
|||
|
|
// + 外部: Arc<Mutex<dyn NyashBox>>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🔍 修正すべきパターン
|
|||
|
|
|
|||
|
|
### 1. **Clone derive削除 + 手動実装**
|
|||
|
|
```rust
|
|||
|
|
// ❌ 削除すべき
|
|||
|
|
#[derive(Debug, Clone)]
|
|||
|
|
|
|||
|
|
// ✅ 変更後
|
|||
|
|
#[derive(Debug)]
|
|||
|
|
pub struct DebugBox {
|
|||
|
|
// ... フィールド
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
impl NyashBox for DebugBox {
|
|||
|
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
|||
|
|
// 手動Clone実装(PR #87パターン)
|
|||
|
|
let tracking_enabled = *self.tracking_enabled.read().unwrap();
|
|||
|
|
let tracked_boxes = self.tracked_boxes.read().unwrap().clone();
|
|||
|
|
let breakpoints = self.breakpoints.read().unwrap().clone();
|
|||
|
|
let call_stack = self.call_stack.read().unwrap().clone();
|
|||
|
|
|
|||
|
|
Box::new(DebugBox {
|
|||
|
|
base: BoxBase::new(),
|
|||
|
|
tracking_enabled: RwLock::new(tracking_enabled),
|
|||
|
|
tracked_boxes: RwLock::new(tracked_boxes),
|
|||
|
|
breakpoints: RwLock::new(breakpoints),
|
|||
|
|
call_stack: RwLock::new(call_stack),
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. **RwLockパターンの体系的適用**
|
|||
|
|
|
|||
|
|
**読み取りアクセス**:
|
|||
|
|
```rust
|
|||
|
|
// ❌ 変更前
|
|||
|
|
let tracked = self.tracked_boxes.lock().unwrap();
|
|||
|
|
let value = tracked.some_property;
|
|||
|
|
|
|||
|
|
// ✅ 変更後
|
|||
|
|
let tracked = self.tracked_boxes.read().unwrap();
|
|||
|
|
let value = tracked.some_property;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**書き込みアクセス**:
|
|||
|
|
```rust
|
|||
|
|
// ❌ 変更前
|
|||
|
|
let mut tracked = self.tracked_boxes.lock().unwrap();
|
|||
|
|
tracked.insert(key, value);
|
|||
|
|
|
|||
|
|
// ✅ 変更後
|
|||
|
|
let mut tracked = self.tracked_boxes.write().unwrap();
|
|||
|
|
tracked.insert(key, value);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🎯 受け入れ基準 (ゴール)
|
|||
|
|
|
|||
|
|
### ✅ 主要目標: コンパイル成功
|
|||
|
|
```bash
|
|||
|
|
$ cargo check --lib
|
|||
|
|
Finished `dev` profile [unoptimized + debuginfo] target(s) in X.XXs
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ✅ 副次目標: クリーンビルド
|
|||
|
|
```bash
|
|||
|
|
$ cargo build --release -j32
|
|||
|
|
Finished `release` profile [optimized] target(s) in X.XXs
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ✅ 検証: DebugBox機能確認
|
|||
|
|
```bash
|
|||
|
|
# DebugBox基本機能テスト
|
|||
|
|
$ ./target/release/nyash test_debug_basic.nyash
|
|||
|
|
✅ DebugBoxがRwLockで動作
|
|||
|
|
|
|||
|
|
# 追跡機能テスト
|
|||
|
|
$ ./target/release/nyash test_debug_tracking.nyash
|
|||
|
|
✅ メモリ追跡・ブレークポイント機能正常
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ✅ 品質保証: パターンの一貫性
|
|||
|
|
```bash
|
|||
|
|
# DebugBoxでのArc<Mutex>排除確認
|
|||
|
|
$ grep -r "Arc<Mutex<" src/boxes/debug_box.rs
|
|||
|
|
# 結果: 0件であるべき
|
|||
|
|
|
|||
|
|
# DebugBoxでのRwLock採用確認
|
|||
|
|
$ grep -r "RwLock<" src/boxes/debug_box.rs | wc -l
|
|||
|
|
# 結果: 4件 (tracking_enabled, tracked_boxes, breakpoints, call_stack)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🛠️ 詳細修正手順
|
|||
|
|
|
|||
|
|
### ステップ1: Clone derive削除
|
|||
|
|
```rust
|
|||
|
|
// src/boxes/debug_box.rs: line 110
|
|||
|
|
// ❌ 削除
|
|||
|
|
#[derive(Debug, Clone)]
|
|||
|
|
|
|||
|
|
// ✅ 変更後
|
|||
|
|
#[derive(Debug)]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ステップ2: 11箇所の.lock()変換
|
|||
|
|
|
|||
|
|
**読み取り専用アクセス (8箇所)**:
|
|||
|
|
```rust
|
|||
|
|
// Lines: 191, 231, 274, 306, 322, 345
|
|||
|
|
self.tracked_boxes.lock().unwrap() → self.tracked_boxes.read().unwrap()
|
|||
|
|
|
|||
|
|
// Line: 182 (別ファイルのinstance.fields)
|
|||
|
|
instance.fields.lock().unwrap() → instance.fields.read().unwrap()
|
|||
|
|
|
|||
|
|
// Line: 274
|
|||
|
|
self.call_stack.lock().unwrap() → self.call_stack.read().unwrap()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**書き込みアクセス (3箇所)**:
|
|||
|
|
```rust
|
|||
|
|
// Lines: 251, 258, 290, 293
|
|||
|
|
self.breakpoints.lock().unwrap() → self.breakpoints.write().unwrap()
|
|||
|
|
self.call_stack.lock().unwrap() → self.call_stack.write().unwrap()
|
|||
|
|
self.tracked_boxes.lock().unwrap() → self.tracked_boxes.write().unwrap()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ステップ3: 手動Clone実装
|
|||
|
|
```rust
|
|||
|
|
impl NyashBox for DebugBox {
|
|||
|
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
|||
|
|
// PR #87確立パターンに従う
|
|||
|
|
let tracking_enabled = *self.tracking_enabled.read().unwrap();
|
|||
|
|
let tracked_boxes = self.tracked_boxes.read().unwrap().clone();
|
|||
|
|
let breakpoints = self.breakpoints.read().unwrap().clone();
|
|||
|
|
let call_stack = self.call_stack.read().unwrap().clone();
|
|||
|
|
|
|||
|
|
Box::new(DebugBox {
|
|||
|
|
base: BoxBase::new(), // 新しいユニークID
|
|||
|
|
tracking_enabled: RwLock::new(tracking_enabled),
|
|||
|
|
tracked_boxes: RwLock::new(tracked_boxes),
|
|||
|
|
breakpoints: RwLock::new(breakpoints),
|
|||
|
|
call_stack: RwLock::new(call_stack),
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 🧪 テスト要件
|
|||
|
|
|
|||
|
|
### 重要なテストケース
|
|||
|
|
1. **DebugBox基本機能**: startTracking, stopTracking, trackBox
|
|||
|
|
2. **メモリレポート**: memoryReport, dumpAll機能
|
|||
|
|
3. **ブレークポイント**: setBreakpoint, traceCall機能
|
|||
|
|
4. **並行アクセス**: RwLockによる複数読み取り者対応
|
|||
|
|
|
|||
|
|
### リグレッション防止
|
|||
|
|
- 既存のDebugBox機能は全て変更なく維持されること
|
|||
|
|
- Everything is Box哲学が保持されること
|
|||
|
|
- パフォーマンスが向上すること (RwLockは並行読み取り可能)
|
|||
|
|
|
|||
|
|
## 📚 参考資料
|
|||
|
|
|
|||
|
|
### 成功事例
|
|||
|
|
- **PR #87**: ArrayBox、MapBox、TimeBoxでRwLockパターンを確立
|
|||
|
|
- **PR #93**: FutureBox二重定義問題の解決例
|
|||
|
|
|
|||
|
|
### アーキテクチャドキュメント
|
|||
|
|
- **Everything is Box哲学**: `docs/説明書/reference/box-design/`
|
|||
|
|
- **RwLockパターン**: PR #87で確立されたパターンに従う
|
|||
|
|
|
|||
|
|
### 関連Issue
|
|||
|
|
- **Issue #92**: FutureBox問題 (解決済み)
|
|||
|
|
- **PR #93**: FutureBox修正 (完了)
|
|||
|
|
|
|||
|
|
## 🚀 修正後の期待される影響
|
|||
|
|
|
|||
|
|
### パフォーマンス向上
|
|||
|
|
- **並行読み取りアクセス**: RwLockは複数読み取り者可能 vs Mutex単一アクセス
|
|||
|
|
- **デバッグ効率化**: メモリ追跡の並行処理対応
|
|||
|
|
- **デッドロック防止**: Arc<Mutex>二重ロックシナリオの完全排除
|
|||
|
|
|
|||
|
|
### 開発ブロック解除
|
|||
|
|
- **Phase 9.5準備完了**: 全Box型がHTTPサーバーテスト対応
|
|||
|
|
- **WASM/AOT開発**: 全Box型がコンパイル互換
|
|||
|
|
- **デバッグ機能**: 本格運用でのパフォーマンス監視可能
|
|||
|
|
- **将来のPhase**: Phase 10+ LLVM作業の堅実な基盤
|
|||
|
|
|
|||
|
|
## ⚠️ 品質要件
|
|||
|
|
|
|||
|
|
**これは最後の仕上げです** - 以下を確実に:
|
|||
|
|
|
|||
|
|
1. **完全なパターン適用**: 全11箇所の.lock() → .read()/.write()変換
|
|||
|
|
2. **型安全性**: Clone実装をRwLockに対応した手動実装で解決
|
|||
|
|
3. **パフォーマンス検証**: RwLock使用が読み取り/書き込みベストプラクティスに従うこと
|
|||
|
|
4. **機能保持**: DebugBoxの全機能を完全に維持すること
|
|||
|
|
5. **アーキテクチャ統一**: 他10個のBox型と同じRwLockパターン適用
|
|||
|
|
|
|||
|
|
目標は、Everything is Box哲学を最適なパフォーマンスで完全に実現する **堅牢で本番レディな実装** です。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**推定作業量**: 1-2時間 (明確に特定された11箇所の修正)
|
|||
|
|
**リスクレベル**: 低 (問題箇所特定済み・修正パターン確立済み)
|
|||
|
|
**依存関係**: 解決まで全Phase 9.5+開発をブロック
|
|||
|
|
**緊急度**: 最高 (他の全Box型は変換完了、DebugBoxのみ残存)
|