Files
hakmem/docs/tls_sll_hdr_reset_investigation_v2.md

144 lines
7.1 KiB
Markdown
Raw Normal View History

# TLS_SLL_HDR_RESET Investigation V2
TLS SLLヘッダー破損を「箱理論」で根治するためのChatGPT向け指示書。現状と仮説を整理し、再現手順と修正パターンをまとめる。
Box境界で原因を特定し、A/Bで戻せる形で修正すること。
## 現在の状況
- ✅ ヘッダー書き込みデフォルトON`core/tiny_region_id.h``HAKMEM_TINY_WRITE_HEADER`未設定で書く)
- ✅ ASan版 `libhakmem_asan.so` では sh8bench baseline / SAFEHEADER いずれも `TLS_SLL_HDR_RESET` 未再現(`sh8bench_baseline_v2.log`, `sh8bench_safeheader_v2.log`
- ❌ リリース版 `libhakmem.so``unified_cache_refill` 内で SIGSEGVTLS SLLに到達する前に崩れる
- ❓ 過去にリリース版 sh8bench で `[TLS_SLL_HDR_RESET]` が発生していたが、現在はクラッシュが優先して観測TLS SLL経路が怪しいまま
### 直近の再現結果release + gdb
- `unified_cache_refill+1128` で SEGV。`meta->freelist`**スラブ基底を 8bit 右シフトした値**(例: slab_base=0x7fffc02d0000 → freelist=0x0000007fffc02d20になっており、生アドレスではない。
- `TinySlabMeta` も汚染されており、`used=0x1e80`capacity=0x0400を大きく超過など整合性崩壊。スラブ内部へのオフセット0x2000相当を持った「圧縮ポインタ」風の値が freelist に混入している可能性が高い。
- 仮説A/B を再強調freelist 書き込み境界free_remote/local/TLS SLL drain/remote drainでポインタが右シフトregion-id?)された形で保存されている箇所を watch する必要あり。
## 新仮説3本
- **仮説A: unified_cache_refill → free → TLS SLL 経路でヘッダー復元漏れ**
- unified cacheで返したバッファがfree時にTLS SLLへ落ちる経路でヘッダー未復元/破損。
- 先にクラッシュするので経路の可視化が必要。
- **仮説B: TLS SLL内部での破損**
- `tiny_tls_sll_push()`がヘッダーを書かない/順序が逆next上書き先行/競合で壊す。
- push直前のヘッダー値が既に壊れている可能性も含め検証。
- **仮説C: Class Mapとヘッダー契約の不整合**
- Class Map経路ではヘッダー不要の前提だが、TLS SLL popは検証を要求。
- `g_write_header`のON/OFFと検証条件がズレている可能性。
## デバッグ手順4ステップ
### Step 1: 詳細ログ有効化
```bash
cd /mnt/workdisk/public_share/hakmem
HAKMEM_TINY_SLL_RING=1 HAKMEM_DEBUG_LEVEL=3 \
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench \
2>&1 | tee sh8bench_tls_sll_debug.log
grep -E "TLS_SLL_HDR_RESET|TLS_SLL_PUSH|TLS_SLL_POP" sh8bench_tls_sll_debug.log | head -50
```
### Step 2: TLS SLL push境界の検証
- 対象: `core/box/tls_sll_box.h``tiny_tls_sll_push()`
- 確認ポイント:
1. `tiny_class_preserves_header` のとき `*(uint8_t*)raw_base = 0xa0 | cls` を必ず実行しているか
2. next書き込みより前にヘッダーを書き、`__atomic_thread_fence(__ATOMIC_RELEASE)` で順序を固定しているか
- 必要なら一時的にトレースを挿入(非リリース限定)して push前ヘッダー値を記録。
### Step 3: unified_cache_refill→free→TLS SLL経路の追跡
- 対象ファイル:
- `core/front/tiny_unified_cache.c` (`unified_cache_refill`, `unified_cache_free_list_drain`)
- `core/hakmem_tiny_free.inc` / `core/box/tiny_front_cold_box.h`free入口→TLS SLL
- 手順:
1. `unified_cache_refill` の out[] 生成直後に `tiny_header_validate` を一度呼んでヘッダーの健全性をリングに記録(ワンショット)。
2. free経路で TLS SLL に入る直前push直前にも同じ base でヘッダー値を記録し、差分を見る。
3. 再現しやすさのため `HAKMEM_TINY_UNIFIED_CACHE=0` で迂回し、TLS SLL経路で再現有無を分離。
### Step 4: SAFEHEADER検証
```bash
HAKMEM_TINY_SLL_SAFEHEADER=1 HAKMEM_TINY_SLL_VALIDATE_HDR=1 \
HAKMEM_TINY_SLL_RING=1 HAKMEM_DEBUG_LEVEL=3 \
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench \
2>&1 | tee sh8bench_safeheader_debug.log
grep -E "TLS_SLL_PUSH_BAD_HDR|TLS_SLL_REJECT|TLS_SLL_HDR_RESET" sh8bench_safeheader_debug.log
```
- push側で拒否が出れば仮説B/Cを優先。
## 修正パターンA/B/C
- **パターンA: TLS SLL pushで常にヘッダー復元境界固定**
- `tiny_tls_sll_push()` の先頭でヘッダーを書き戻し + release fence。
- Box境界をpushに集約し、他経路の漏れを吸収。
- **パターンB: unified_cache_refill境界でヘッダー確定**
- `unified_cache_refill` が out[] へ入れる直前に `tiny_header_write_if_preserved` を実行。
- free経路でTLS SLLに落ちる前にヘッダーが既に正しいことを保証。
- 必要なら `HAKMEM_TINY_UNIFIED_CACHE=0` でA/B切替を残す。
- **パターンC: Class Mapと検証条件の整合**
- `g_write_header` がOFFのときは TLS SLL pop 検証をスキップするか、Class Map経路をTLS SLLから分離。
- ONの場合は push/pop 双方で `tiny_class_preserves_header` を強制し、Fail-Fastで露呈。
## 環境変数
```bash
# ログ/検証
HAKMEM_TINY_SLL_RING=1
HAKMEM_TINY_SLL_VALIDATE_HDR=1
HAKMEM_TINY_SLL_SAFEHEADER=1
HAKMEM_DEBUG_LEVEL=3
# 経路A/B切替
HAKMEM_TINY_WRITE_HEADER=1 # 既定でON省略可
HAKMEM_TINY_UNIFIED_CACHE=0 # unified cache無効化で分離試験
# 追加トレース
HAKMEM_WRAP_DIAG=1
```
## ビルド方法
```bash
cd /mnt/workdisk/public_share/hakmem
find . -name "*.o" -delete
find . -name "*.so" -delete
# リリース相当
make shared -j8
# ASan
make asan-shared-alloc -j8
```
## テスト手順
```bash
# ベースライン(リリース): クラッシュ/RESETの有無確認
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench \
2>&1 | tee sh8bench_baseline_v3.log
# unified cache切替
HAKMEM_TINY_UNIFIED_CACHE=0 LD_PRELOAD=./libhakmem.so \
./mimalloc-bench/out/bench/sh8bench 2>&1 | tee sh8bench_uc_off.log
# SAFEHEADER強化
HAKMEM_TINY_SLL_SAFEHEADER=1 HAKMEM_TINY_SLL_VALIDATE_HDR=1 \
HAKMEM_TINY_SLL_RING=1 HAKMEM_DEBUG_LEVEL=3 \
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench \
2>&1 | tee sh8bench_safeheader_v3.log
```
- いずれも `[TLS_SLL_HDR_RESET]` や SIGSEGV が出た場合はリング先頭〜直前のイベントを確認。
## 調査対象ファイル(優先度順)
- `core/front/tiny_unified_cache.c` 仮説A/Bの境界
- `core/box/tls_sll_box.h` push/pop実装、仮説B/A
- `core/hakmem_tiny_free.inc`, `core/box/tiny_front_cold_box.h` free入口→TLS SLL
- `core/tiny_region_id.h`, `core/box/tiny_header_box.h` ヘッダー契約とClass Map、仮説C
- 参考: `docs/tls_sll_header_corruption_investigation.md`(初回調査ログ)
---
この指示書をChatGPTに渡せば、`TLS_SLL_HDR_RESET` と unified cacheクラッシュの根本原因を箱境界で特定・修正できる。
Step 2〜3で経路を可視化し、A/B/Cのいずれかまたは組み合わせで確実に「書くべき場所でヘッダーを復元する」こと。