# 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秒クラッシュの修正