Files
hakmem/docs/CRASH_180s_INVESTIGATION_GUIDE.md

274 lines
6.9 KiB
Markdown
Raw Normal View History

# 180秒クラッシュ修正指示書 (2025-12-04)
**Status**: 未解決Pre-existing bug, not introduced by Release Guard Box
**Crash Details**:
- Time to crash: 180秒安定
- Root cause: TLS SLL push操作中のSIGSEGV
- Release Guard Box: クラッシュ前に呼ばれていない(別問題)
- Current commit: 1ac502af5 (Release Guard Box)
---
## 📋 調査フロー
### Phase 1: クラッシュポイント特定
**目標**: `SIGSEGV` の正確なアドレスと命令を特定
```bash
# 1. gdb でクラッシュ再現
cd /mnt/workdisk/public_share/hakmem
make clean && make RELEASE=0 # デバッグシンボル有効
# 2. gdb 実行
gdb --args bash -c 'env LD_PRELOAD=/mnt/workdisk/public_share/hakmem/libhakmem.so /mnt/workdisk/public_share/hakmem/mimalloc-bench/out/bench/sh8bench'
# 3. gdb 内で:
(gdb) run
# ... 180秒待つ ...
# クラッシュ時に自動停止
# 4. スタックトレース確認
(gdb) bt
(gdb) frame 0
(gdb) disassemble
(gdb) info registers
```
**期待される出力**:
- `#0 ... in tiny_alloc_fast_push ...` または
- `#0 ... in tls_sll_push ...` または
- `#0 ... in slab_index_for ...` などのTLS SLL関連
---
### Phase 2: クラッシュのコンテキスト分析
**目標**: クラッシュ前の状態を理解
```c
// コアの質問:
1. クラッシュしたポインタ (ptr) は何か?
→ gdb: print ptr
→ gdb: x/16x ptr (メモリダンプ)
2. SuperSlab* ss は有効か?
→ gdb: print ss->magic (SUPERSLAB_MAGIC = 0x53535342 であるべき)
→ gdb: print ss->refcount (> 0 であるべき)
3. slab_idx は有効か?
→ gdb: print slab_idx
→ gdb: print ss_slabs_capacity(ss)
4. TinySlabMeta* meta は有効か?
→ gdb: print meta->class_idx
→ gdb: print meta->capacity
→ gdb: print meta->used
5. head ポインタは?
→ gdb: print g_tls_sll[class_idx].head
→ gdb: x/16x g_tls_sll[class_idx].head (メモリダンプ)
```
---
### Phase 3: Reproducibility 検証
**目標**: クラッシュが100%再現するかを確認
```bash
# 環境変数をクリア(過去の診断ログ無効化)
unset HAKMEM_TINY_SLL_NEXTCLS
unset HAKMEM_TINY_SLL_NEXTTAG
unset HAKMEM_TINY_SLL_HEADCLS
unset HAKMEM_DEBUG_COUNTER
unset HAK_DEBUG_LOG_FREQ
# 3回テスト
for i in 1 2 3; do
echo "=== Test $i ==="
timeout 190 env LD_PRELOAD=/mnt/workdisk/public_share/hakmem/libhakmem.so \
/mnt/workdisk/public_share/hakmem/mimalloc-bench/out/bench/sh8bench 2>&1 | tail -20
echo "EXIT_CODE: $?"
done
```
**期待される結果**:
- Test 1, 2, 3: すべて ~180秒でクラッシュ100%再現性)
---
## 🔍 疑い容疑者リスト
前セッションの分析から、以下が候補:
### 候補1: TLS SLL next ポインタの破壊
**症状**: `next` が不正なアドレスを指している
**チェック方法**:
```bash
# Phase 2 の gdb コマンドで:
(gdb) print g_tls_sll[class_idx].head->next
# 0x0, NULL, または特定のメモリアドレス?
# 有効な全体メモリ範囲外か?
```
**修正アプローチ** (if 原因なら):
- `tls_sll_push_impl()` での next ポインタ設定をチェック
- `tiny_alloc_fast_push()` での pointer conversion をチェック
- メモリバリアの不足?
---
### 候補2: SuperSlab refcount の不一致
**症状**: refcount が 0 になり、SuperSlab が free されてから TLS SLL が access している
**チェック方法**:
```bash
# Phase 2 の gdb コマンドで:
(gdb) print ss->refcount
# 0 なら??? → Layer 1 (refcount pinning) が機能していない可能性
# > 0 なら OK
```
**修正アプローチ** (if 原因なら):
- `tiny_alloc_fast_push()` の atomic_fetch_add を確認
- `tls_sll_pop_impl()` の atomic_fetch_sub を確認
- Race condition
---
### 候補3: slab_idx の計算エラー
**症状**: slab_idx が範囲外になり、`ss->slabs[slab_idx]` が不正なメモリを access
**チェック方法**:
```bash
# Phase 2 の gdb コマンドで:
(gdb) print slab_idx
(gdb) print ss_slabs_capacity(ss)
# slab_idx >= capacity? → これが問題
```
**修正アプローチ** (if 原因なら):
- `slab_index_for(ss, ptr)` の実装を再確認
- Boundary check の見落とし?
---
### 候補4: class_idx の不整合
**症状**: TLS SLL[class_idx] が破壊されている
**チェック方法**:
```bash
# Phase 2 の gdb コマンドで:
(gdb) print class_idx
(gdb) print meta->class_idx
# 一致してるか?ズレてるか?
```
**修正アプローチ** (if 原因なら):
- `tiny_get_class_from_ss()` の返り値を確認
- class_idx と meta->class_idx の関係を再確認
---
### 候補5: メモリレイアウトの仮定ずれ
**症状**: sizeof(TinySlabMeta) や stride が変わり、ポインタ計算がズレている
**チェック方法**:
```bash
# gdb で:
(gdb) print sizeof(TinySlabMeta)
(gdb) print sizeof(TinySlab)
(gdb) print sizeof(SuperSlab)
# コンパイル時の定義と一致?
```
---
## 📊 デバッグ戦略
### ステップ1: スタックトレース取得30分
```bash
make clean && make RELEASE=0
# gdb でスタックトレース取得
gdb --args bash -c '...'
(gdb) run
# クラッシュ待機
(gdb) bt full
(gdb) frame 0; disassemble
# ファイルに出力
```
### ステップ2: コンテキスト分析1時間
- gdb で各変数を print
- メモリダンプで破壊パターンを特定
- 前後のメモリ状態を記録
### ステップ3: 仮説検証2時間
- 候補ごとに検証コード追加
- 特定のクラスやスレッド数で再現性確認
- ログ出力で実行フロー追跡
### ステップ4: 修正実装1-3時間
- 根本原因に応じて修正
- テスト60秒 → 120秒 → 180秒 → 240秒
---
## 🛠️ 実装チェックリスト
修正時には以下を確認:
- [ ] スタックトレースから特定の関数が明確か
- [ ] 該当ファイルを読んで実装を理解した
- [ ] 候補1-5から最も可能性高い仮説を選んだ
- [ ] 修正方法を3つ以上考えた安全性が高い順
- [ ] 修正実装後、180秒テストで確認
- [ ] 240秒テストで追加マージンを確保
- [ ] ドキュメント更新
---
## 📚 関連ファイル
**主要ファイル**:
- `core/tiny_alloc_fast.inc.h` - tiny_alloc_fast_push (line 879)
- `core/tiny_free_fast.inc.h` - tiny_free_fast (line 195)
- `core/box/tls_sll_box.h` - TLS SLL 実装
- `core/hakmem_tiny_superslab.h` - SuperSlab 定義
**ヘッダ**:
- `core/tiny_atomic.h` - atomic 操作
- `core/slab_handle.h` - slab_index_for()
---
## 🎯 成功判定基準
修正が完了した → 以下をすべてPASS:
- ✅ 180秒テスト: EXIT_CODE 0, SIGSEGV 0件
- ✅ 240秒テスト: EXIT_CODE 0, SIGSEGV 0件
- ✅ スタックトレース: TLS SLL/alloc_fast_push 関連なし
- ✅ ログ: [TLS_SLL_*], [ERROR] 無し
- ✅ メモリ: RSS 安定 (increase < 10%)
---
**作成日**: 2025-12-04
**対象**: 180秒クラッシュの修正