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

7.1 KiB
Raw Blame History

TLS_SLL_HDR_RESET Investigation V2

TLS SLLヘッダー破損を「箱理論」で根治するためのChatGPT向け指示書。現状と仮説を整理し、再現手順と修正パターンをまとめる。
Box境界で原因を特定し、A/Bで戻せる形で修正すること。

現在の状況

  • ヘッダー書き込みデフォルトONcore/tiny_region_id.hHAKMEM_TINY_WRITE_HEADER未設定で書く)
  • ASan版 libhakmem_asan.so では sh8bench baseline / SAFEHEADER いずれも TLS_SLL_HDR_RESET 未再現(sh8bench_baseline_v2.log, sh8bench_safeheader_v2.log
  • リリース版 libhakmem.sounified_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=0x1e80capacity=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: 詳細ログ有効化

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.htiny_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.hfree入口→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検証

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で露呈。

環境変数

# ログ/検証
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

ビルド方法

cd /mnt/workdisk/public_share/hakmem
find . -name "*.o" -delete
find . -name "*.so" -delete

# リリース相当
make shared -j8

# ASan
make asan-shared-alloc -j8

テスト手順

# ベースライン(リリース): クラッシュ/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のいずれかまたは組み合わせで確実に「書くべき場所でヘッダーを復元する」こと。