Files
hakmem/docs/tls_sll_hdr_reset_investigation_v2.md
2025-12-03 10:34:39 +09:00

144 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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のいずれかまたは組み合わせで確実に「書くべき場所でヘッダーを復元する」こと。