Created comprehensive evaluation of ChatGPT's diagnostic work (commit 054645416).
Summary:
- 40% root cause fixes (allocation class, TLS SLL validation)
- 40% defensive mitigations (registry fallback, push rejection)
- 20% diagnostic tools (debug output, traces)
- Root cause (16-byte pointer offset) remains UNSOLVED
Analysis Includes:
- Technical evaluation of each change (root fix vs symptom treatment)
- 6 root cause pattern candidates with code examples
- Clear next steps for ChatGPT (Tasks A/B/C with priority)
- Performance impact assessment (< 2% overhead)
Key Findings:
✅ SuperSlab allocation class fix - structural bug eliminated
✅ TLS SLL validation - prevents list corruption (defensive)
⚠️ Registry fallback - may hide registration bugs
❌ 16-byte offset source - unidentified
Next Actions for ChatGPT:
A. Full pointer arithmetic audit (Magazine ⇔ TLS SLL paths)
B. Enhanced logging at HDR_RESET point (pointer provenance)
C. Headerless flag runtime verification (build consistency)
🤖 Generated with Claude Code (https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
421 lines
11 KiB
Markdown
421 lines
11 KiB
Markdown
# ChatGPT進捗報告と残存問題 (2025-12-03)
|
||
|
||
**最終更新**: 2025-12-03
|
||
**Commit**: 054645416
|
||
**ステータス**: 🟡 部分的緩和、根本原因は未解決
|
||
|
||
---
|
||
|
||
## 📊 実施された変更(ChatGPT作業)
|
||
|
||
### 1. SuperSlab Registry Fallback ✅ 防御的対策
|
||
|
||
**場所**: `core/hakmem_super_registry.h`
|
||
|
||
**変更内容**:
|
||
```c
|
||
// ハッシュマップでミスした場合、レガシーテーブルをプローブ
|
||
if (ss == NULL) {
|
||
// 全lg_sizeをループしてレジストリテーブルから検索
|
||
for (int lg = SUPERSLAB_LG_MIN; lg <= SUPERSLAB_LG_MAX; lg++) {
|
||
// linear probing with SUPER_MAX_PROBE
|
||
}
|
||
}
|
||
```
|
||
|
||
**評価**:
|
||
- ✅ **効果**: 初期化中のNULL返却を防ぐ
|
||
- ⚠️ **懸念**: 登録バグを隠す可能性(なぜハッシュマップにない?)
|
||
- 📈 **コスト**: +10-30サイクル(コールドパスのみ)
|
||
|
||
**根治 or 対症療法?**: **対症療法** - レジストリ不整合の根本原因は未解決
|
||
|
||
---
|
||
|
||
### 2. TLS SLL Push時の検証 ✅ リスト汚染防止
|
||
|
||
**場所**: `core/box/tls_sll_box.h`
|
||
|
||
**変更内容**:
|
||
```c
|
||
// SuperSlab lookup 失敗時にpushを拒否
|
||
if (!ss) {
|
||
fprintf(stderr, "[TLS_SLL_PUSH_NO_SS] cls=%d base=%p\n", ...);
|
||
return false; // pushを拒否
|
||
}
|
||
|
||
// class_idx ミスマッチ検出時もpushを拒否
|
||
if (meta_cls != class_idx) {
|
||
fprintf(stderr, "[TLS_SLL_PUSH_META_MISMATCH] ...\n");
|
||
return false; // pushを拒否
|
||
}
|
||
```
|
||
|
||
**評価**:
|
||
- ✅ **効果**: 不正なポインタによるリスト汚染を早期ブロック
|
||
- ✅ **安全性**: フリーリスト破損を防ぐ
|
||
- 📈 **コスト**: +5-10サイクル/push(許容範囲)
|
||
|
||
**根治 or 対症療法?**: **根治寄り** - 早期検出で二次被害を防ぐ
|
||
|
||
---
|
||
|
||
### 3. SuperSlab Allocation クラス指定修正 ✅ 根治
|
||
|
||
**場所**: `core/superslab_allocate.c`
|
||
|
||
**変更内容**:
|
||
```c
|
||
// 以前: ダミー class=8 を渡してた → OOB
|
||
sp_internal_allocate_superslab(lg, 8 /* dummy */);
|
||
|
||
// 修正後: 実際のclass_idxを渡す
|
||
sp_internal_allocate_superslab(lg, class_idx);
|
||
```
|
||
|
||
**評価**:
|
||
- ✅ **効果**: class=8 によるOOBアクセスを根絶
|
||
- ✅ **構造**: 正しいメタデータが登録される
|
||
- 📈 **コスト**: 0(既存パラメータの修正のみ)
|
||
|
||
**根治 or 対症療法?**: **✅ 根治** - 構造的バグの修正
|
||
|
||
---
|
||
|
||
### 4. デバッグ出力追加 ✅ 診断ツール
|
||
|
||
**場所**: 複数ファイル
|
||
|
||
**変更内容**:
|
||
- 最初256回のpush/popをトレース
|
||
- 最初4回のミスマッチをログ出力
|
||
- SuperSlab登録状態を出力
|
||
|
||
**評価**:
|
||
- ✅ **効果**: 問題の可視化
|
||
- ✅ **オーバーヘッド**: 初回のみ(本番影響なし)
|
||
|
||
**根治 or 対症療法?**: **診断ツール** - 修正ではない
|
||
|
||
---
|
||
|
||
### 5. TLS Hint Box 削除 ⏳ 一時的撤退
|
||
|
||
**場所**: `core/box/ss_tls_hint_box.{c,h}`
|
||
|
||
**変更内容**:
|
||
- Phase 1最適化を一旦削除
|
||
- 安定性優先のため
|
||
|
||
**評価**:
|
||
- ✅ **効果**: 調査対象を減らす
|
||
- ⚠️ **トレードオフ**: Phase 1成果を失う
|
||
|
||
**根治 or 対症療法?**: **戦略的撤退** - 問題切り分けのため
|
||
|
||
---
|
||
|
||
## 🔴 残存する問題(CRITICAL)
|
||
|
||
### 問題の症状
|
||
|
||
```
|
||
[TLS_SLL_HDR_RESET] cls=1 base=0x... got=0x31 expect=0xa1
|
||
Segmentation fault (exit code 139)
|
||
```
|
||
|
||
**発生タイミング**: sh8bench実行後 ~60秒
|
||
**頻度**: 100%再現(60秒後)
|
||
**影響**: 全ての構成に影響(共通コードパス)
|
||
|
||
---
|
||
|
||
### 技術的詳細
|
||
|
||
#### 1. ポインタオフセット異常
|
||
|
||
```
|
||
期待: クラス1のベースポインタ (16Bストライド境界)
|
||
実際: 期待値 + 16B (次のブロックの境界)
|
||
|
||
差分: +16バイト = クラス1のストライド1個分
|
||
```
|
||
|
||
**これが意味すること**:
|
||
- ポインタが**隣のブロック**を指してる
|
||
- = 本来のブロックではない
|
||
- = Use-After-Free または ポインタ演算エラー
|
||
|
||
#### 2. SuperSlab Lookup 失敗
|
||
|
||
```c
|
||
SuperSlab* ss = hak_super_lookup(ptr); // → NULL
|
||
```
|
||
|
||
**これが意味すること**:
|
||
- そのポインタは**割り当てられてない領域**
|
||
- または**既に解放済み**
|
||
- または**ポインタ演算が間違ってる**
|
||
|
||
#### 3. ヘッダー破損
|
||
|
||
```
|
||
期待: 0xa1 (0xa0 MAGIC | class_idx=1)
|
||
実際: 0x31 (ASCIIの '1' またはユーザーデータ)
|
||
```
|
||
|
||
**これが意味すること**:
|
||
- ヘッダー位置に**ユーザーデータが存在**
|
||
- = ヘッダーが書かれてない
|
||
- または ヘッダーが上書きされた
|
||
- または ポインタが間違った位置を指してる
|
||
|
||
---
|
||
|
||
## 🔍 根本原因の候補(6パターン)
|
||
|
||
### パターンA: ポインタ演算の二重適用 ⭐⭐⭐
|
||
|
||
```c
|
||
// 疑わしいパターン:
|
||
void* user = base + 16; // +16 (正しい)
|
||
// ... 後で ...
|
||
void* wrong = user + 16; // 再度 +16 (誤り) ← ★これ?
|
||
```
|
||
|
||
**チェック箇所**:
|
||
- `ptr_conversion_box.h` の `ptr_user_to_base()`
|
||
- Magazine ⇔ TLS SLL の変換パス
|
||
- Refill/Spill/Drain の全経路
|
||
|
||
### パターンB: Magazine Spill での型変換漏れ ⭐⭐
|
||
|
||
```c
|
||
// commit f3f75ba3d で修正済みだが...
|
||
void* p = mag->items[i].ptr; // これはUSER? BASE?
|
||
tls_sll_push(class_idx, p); // もし間違った型なら +16 ずれる
|
||
```
|
||
|
||
**チェック箇所**:
|
||
- `hakmem_tiny_refill.inc.h` (refill経路)
|
||
- Magazine drain経路
|
||
- Magazine → TLS SLL の全パス
|
||
|
||
### パターンC: Headerless モードの干渉 ⭐⭐
|
||
|
||
```c
|
||
// Headerless OFF なのに、どこかで ON のコードが動いてる?
|
||
#if HAKMEM_TINY_HEADERLESS
|
||
return base; // offset 0
|
||
#else
|
||
return base + 1; // offset 1
|
||
#endif
|
||
|
||
// もし混在してたら...
|
||
// Push時: offset 1 で計算 → base + 1
|
||
// Pop時: offset 0 で計算 → base ← ズレる
|
||
```
|
||
|
||
**チェック箇所**:
|
||
- Makefile の `-DHAKMEM_TINY_HEADERLESS=0` が全ファイルに適用されてるか
|
||
- 条件コンパイルの境界
|
||
- `tiny_layout_box.h` の `tiny_user_offset()` の全呼び出し元
|
||
|
||
### パターンD: Use-After-Free ⭐
|
||
|
||
```c
|
||
// どこかで解放済みポインタを再利用してる?
|
||
free(p1); // p1 を解放
|
||
// ... 後で ...
|
||
void* p2 = alloc(); // p1 と同じアドレスを再割り当て
|
||
free(p1); // ★ Double-Free!
|
||
```
|
||
|
||
**チェック箇所**:
|
||
- Magazine の重複エントリ
|
||
- TLS SLL の循環参照
|
||
- Freelist の破損
|
||
|
||
### パターンE: Adjacent Block Overflow ⭐
|
||
|
||
```c
|
||
// 隣接ブロックからのオーバーフロー
|
||
char* block1 = alloc(15); // クラス1 (16B)
|
||
strcpy(block1, "0123456789ABCDEF!"); // 17バイト書き込み ← ★オーバーフロー
|
||
// → block2 のヘッダーを破壊
|
||
```
|
||
|
||
**チェック箇所**:
|
||
- sh8bench のメモリアクセスパターン
|
||
- Boundary check の有無
|
||
|
||
### パターンF: Atomic Fence 欠如 ⭐
|
||
|
||
```c
|
||
// ヘッダー書き込みと push の順序が逆転?
|
||
*hdr = magic; // ヘッダー書き込み
|
||
tls_sll_push(...); // push
|
||
|
||
// CPU/コンパイラが並び替え:
|
||
tls_sll_push(...); // ★ 先に実行
|
||
*hdr = magic; // 後で実行 ← 遅すぎる
|
||
```
|
||
|
||
**チェック箇所**:
|
||
- ヘッダー書き込み直後に `atomic_thread_fence()` があるか
|
||
- Free path の順序保証
|
||
|
||
---
|
||
|
||
## 📋 次のChatGPTタスク(優先順位順)
|
||
|
||
### Task A: ポインタ演算の完全監査 ⭐⭐⭐
|
||
|
||
**目的**: パターンA/B/Cを特定
|
||
|
||
**手順**:
|
||
1. `ptr_conversion_box.h` の全使用箇所をリスト化
|
||
2. Magazine ⇔ TLS SLL の変換パス全てを追跡
|
||
3. 2重オフセット適用がないか確認
|
||
4. Headerless フラグの一貫性確認
|
||
|
||
**期待成果**: 「どこで +16 が余分に適用されたか」を特定
|
||
|
||
---
|
||
|
||
### Task B: [TLS_SLL_HDR_RESET] 時の詳細ログ追加 ⭐⭐⭐
|
||
|
||
**目的**: 16バイトずれの直接原因を特定
|
||
|
||
**実装**:
|
||
```c
|
||
// tls_sll_box.h の HDR_RESET 検出時:
|
||
fprintf(stderr,
|
||
"[TLS_SLL_HDR_RESET_DETAIL]\n"
|
||
" class_idx: %d\n"
|
||
" base_ptr: %p\n"
|
||
" base_ptr_expected: %p\n"
|
||
" offset_delta: %+ld\n"
|
||
" came_from: %s\n"
|
||
" allocation_trace: %s\n",
|
||
class_idx,
|
||
raw_base,
|
||
raw_base - 16, // 期待値(-16したもの)
|
||
16,
|
||
where,
|
||
get_alloc_trace(raw_base));
|
||
```
|
||
|
||
**期待成果**: 「そのポインタがどこから来たか」を特定
|
||
|
||
---
|
||
|
||
### Task C: Headerless フラグの実行時確認 ⭐⭐
|
||
|
||
**目的**: パターンCを検証
|
||
|
||
**実装**:
|
||
```c
|
||
// tiny_layout_box.h に追加:
|
||
static inline void verify_headerless_mode(void) {
|
||
static int once = 0;
|
||
if (!once) {
|
||
once = 1;
|
||
fprintf(stderr, "[HEADERLESS_MODE_CHECK]\n");
|
||
#if HAKMEM_TINY_HEADERLESS
|
||
fprintf(stderr, " HAKMEM_TINY_HEADERLESS=1 (ON)\n");
|
||
#else
|
||
fprintf(stderr, " HAKMEM_TINY_HEADERLESS=0 (OFF)\n");
|
||
#endif
|
||
fprintf(stderr, " tiny_user_offset(1)=%zu\n", tiny_user_offset(1));
|
||
}
|
||
}
|
||
|
||
// hakmem.c の init で呼び出す
|
||
```
|
||
|
||
**期待成果**: ビルドとランタイムの整合性確認
|
||
|
||
---
|
||
|
||
## 🎯 評価サマリー
|
||
|
||
| カテゴリ | 評価 | 説明 |
|
||
|---------|------|------|
|
||
| **根治的修正** | ✅ 40% | SuperSlab allocation class修正、TLS SLL検証 |
|
||
| **防御的対策** | ⚠️ 40% | Registry fallback、push validation |
|
||
| **診断ツール** | ✅ 20% | デバッグ出力、トレース |
|
||
| **根本原因** | ❌ 未解決 | 16バイトずれの源泉が不明 |
|
||
| **パフォーマンス** | ✅ 良好 | < 2% オーバーヘッド |
|
||
|
||
---
|
||
|
||
## ✅ 良い点
|
||
|
||
1. **SuperSlab allocation class修正** - 構造的バグを根治
|
||
2. **TLS SLL検証** - リスト汚染を早期ブロック
|
||
3. **デバッグ出力** - 問題の可視化に貢献
|
||
4. **戦略的撤退** - Phase 1削除で調査対象を絞った
|
||
|
||
---
|
||
|
||
## ⚠️ 懸念点
|
||
|
||
1. **Registry fallback は対症療法** - なぜハッシュマップにない?
|
||
2. **根本原因は未解決** - 16バイトずれの源泉が不明
|
||
3. **60秒後再発** - 累積的な問題が残存
|
||
4. **Phase 1成果を失った** - TLS Hint Box削除
|
||
|
||
---
|
||
|
||
## 📌 次のステップ(明確な指示)
|
||
|
||
**ChatGPTへの指示**:
|
||
|
||
```
|
||
良い進捗だけど、根本原因が残ってる。
|
||
|
||
問題:
|
||
- ポインタが16バイトずれてる(クラス1 → クラス2境界)
|
||
- 60秒後に再発(累積的)
|
||
- SuperSlab lookup失敗
|
||
|
||
次のタスク(優先順位順):
|
||
|
||
A. ポインタ演算の完全監査 ⭐⭐⭐
|
||
- Magazine ⇔ TLS SLL の全変換パスを追跡
|
||
- 2重オフセット適用がないか確認
|
||
- Headerless フラグの一貫性確認
|
||
|
||
B. [TLS_SLL_HDR_RESET] 時の詳細ログ追加 ⭐⭐⭐
|
||
- 期待値 vs 実際値
|
||
- ポインタの来歴(どこから?)
|
||
- 割り当てトレース
|
||
|
||
C. Headerless フラグの実行時確認 ⭐⭐
|
||
- ビルドとランタイムの整合性確認
|
||
|
||
期待成果:
|
||
- 「いつ、どこで +16 が余分に適用されたか」を特定
|
||
- そのコードを修正(1-3行)
|
||
```
|
||
|
||
---
|
||
|
||
## 📖 関連ドキュメント
|
||
|
||
| ドキュメント | 目的 |
|
||
|------------|------|
|
||
| `CHATGPT_HANDOFF_TLS_DIAGNOSIS.md` | 7ステップ診断手順 |
|
||
| `TLS_SLL_HEADER_CORRUPTION_DIAGNOSIS.md` | 6パターン詳細 (1,150行) |
|
||
| `STATUS_2025_12_03_CURRENT.md` | プロジェクト全体ステータス |
|
||
|
||
---
|
||
|
||
**結論**: 部分的に前進したが、**根本原因(16バイトずれ)は未解決**。次のタスクA-Cで特定が期待される。
|
||
|
||
---
|
||
|
||
*作成: Claude Code (2025-12-03)*
|
||
*Commit: 054645416*
|