Files
hakmem/docs/sh8bench_debug_instruction.md
Moe Charm (CI) 4cc2d8addf sh8bench修正: LRU registry未登録問題 + self-heal修復
問題:
  - sh8benchでfree(): invalid pointer発生
  - header=0xA0だがsuperslab registry未登録のポインタがlibcへ

根本原因:
  - LRU pop時にhak_super_register()が呼ばれていなかった
  - hakmem_super_registry.c:hak_ss_lru_pop()の設計不備

修正内容:

1. 根治修正 (core/hakmem_super_registry.c:466)
   - LRU popしたSuperSlabを明示的にregistry再登録
   - hak_super_register((uintptr_t)curr, curr) 追加
   - これによりfree時のhak_super_lookup()が成功

2. Self-heal修復 (core/box/hak_wrappers.inc.h:387-436)
   - Safety net: 未登録SuperSlabを検出して再登録
   - mincore()でマッピング確認 + magic検証
   - libcへの誤ルート遮断(free()クラッシュ回避)
   - 詳細デバッグログ追加(HAKMEM_WRAP_DIAG=1)

3. デバッグ指示書追加 (docs/sh8bench_debug_instruction.md)
   - TLS_SLL_HDR_RESET問題の調査手順

テスト:
  - cfrac, larson等の他ベンチマークは正常動作確認
  - sh8benchのTLS_SLL_HDR_RESET問題は別issue(調査中)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 09:15:59 +09:00

5.4 KiB
Raw Blame History

sh8bench TLS Header Corruption Debug Instruction

問題の概要

hakmemメモリアロケータをLD_PRELOADでsh8benchベンチマークに適用すると、以下のエラーが発生してベンチマークが正常に完了しない

[TLS_SLL_HDR_RESET] cls=1 base=0x7c18d6bc7858 got=0x61 expect=0xa1 count=0

環境情報

  • ビルド構成: Release build with -O3 -DNDEBUG -flto -march=native
  • 問題の発生状況: sh8benchでのみ発生、cfracなど他のベンチマークは正常動作
  • エラーの意味: TLSThread-Local StorageのSingle-Linked-List Header が破損している

エラー詳細

  • cls=1: サイズクラス1小さいメモリブロック
  • base: Slabのベースアドレス
  • got=0x61: 実際に読み取られたヘッダー値
  • expect=0xa1: 期待されるヘッダー値サイズクラス1のマーカー
  • count=0: リセット回数

期待値0xa1のフォーマット

  • 上位4bit (0xa): サイズクラスインデックス + マーカー
  • 下位4bit (0x1): サイズクラスインデックス

実際の値0x61は破損している。

コード箇所

エラー出力箇所

ファイル: core/box/tls_sll_box.h

該当するコードを探してください(TLS_SLL_HDR_RESETで検索)。

関連する可能性のあるコード

  1. TLS SLL (Single-Linked-List) 操作

    • core/box/tls_sll_box.h - TLSフリーリスト管理
    • ヘッダーの読み書き操作
  2. Tiny allocation fast path

    • core/tiny_alloc_fast_push.c
    • core/tiny_alloc_fast_sfc.inc.h
    • core/hakmem_tiny_sfc.c
  3. Thread-local state

    • core/hakmem_tiny_tls_state_box.inc

調査すべきポイント

1. ヘッダー値の設定・検証ロジック

  • ヘッダー値0xa1がどこで設定されているか
  • ヘッダー値の検証がどこで行われているか
  • マルチスレッド環境でのヘッダー操作の競合

2. sh8bench固有の特性

# sh8benchのソースコードを確認
cat mimalloc-bench/bench/sh8bench/sh8bench.c

sh8benchがどのような割り当てパターンを行うか

  • スレッド数: 8
  • 割り当てサイズ
  • 割り当て/解放の順序
  • スレッド間でのメモリ共有パターン

3. 競合条件の可能性

  • 複数スレッドが同時に同じSlabにアクセス
  • TLSの初期化タイミング
  • フリーリストの操作中の競合

4. メモリ破壊の原因候補

  • Use-after-free
  • Double-free
  • バッファオーバーラン
  • アライメント問題
  • 初期化されていないメモリの使用

デバッグ手順

Step 1: 最小再現ケースの作成

# sh8benchを直接実行
cd /mnt/workdisk/public_share/hakmem
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench

Step 2: デバッグビルドで詳細情報を取得

# デバッグビルドNDEFUGを外す
make clean-objects  # または rm -f *.o
make shared -j8 EXTRA_CFLAGS="-g -O0"

# 詳細ログ有効化
HAKMEM_DEBUG_LEVEL=3 LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench 2>&1 | tee debug.log

Step 3: コード検証

core/box/tls_sll_box.hで以下を確認:

  1. ヘッダー値の計算ロジック

    // 期待されるヘッダー値の計算(例)
    uint8_t expected_header = (class_idx << 4) | class_idx;
    
  2. ヘッダー検証のタイミング

    • push時
    • pop時
    • リセット時
  3. 競合保護

    • アトミック操作の使用
    • TLS変数へのアクセス制御

Step 4: Valgrind/AddressSanitizerによる検証

# AddressSanitizer
make clean-objects
make shared EXTRA_CFLAGS="-fsanitize=address -g -O1"
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench

# ThreadSanitizer
make clean-objects
make shared EXTRA_CFLAGS="-fsanitize=thread -g -O1"
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench

期待される修正

  1. 競合条件の修正

    • 適切なロック機構の追加
    • アトミック操作への変更
  2. 初期化の改善

    • TLS変数の適切な初期化タイミング
    • ヘッダー値の確実な設定
  3. 検証強化

    • より早期のエラー検出
    • デバッグ情報の追加

参考情報

ビルド方法

cd /mnt/workdisk/public_share/hakmem
make shared -j8  # Release build

動作する他のベンチマーク(比較用)

# cfrac - 正常動作
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/cfrac 17545186520507317056371138836327483792789528

# larson - 正常動作(確認が必要)
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/larson 10 7 8 100 10000

追加のヒント

  • 前回のcommitでmalloc_countのアトミック操作を削除して性能が改善17s→10s
  • この変更は関係ないrevertしても同じエラーが発生
  • エラーメッセージはTLS_SLL_HDR_RESETなので、TLSのSingle-Linked-List操作に関連

質問すべきこと

  1. ヘッダー値0xa1はどのように計算されているか
  2. なぜsh8benchだけでこの問題が発生するのか
  3. got=0x61という値には何か意味があるか0x61 = 'a' ASCII
  4. TLS_SLL_HDR_RESETはどのタイミングで呼ばれるか

この指示書を使って、sh8benchでのTLSヘッダー破損問題をデバッグし、修正してください。