Documentation: - Created docs/DEFENSIVE_LAYERS_MAPPING.md documenting all 5 defensive layers - Maps which symptoms each layer suppresses - Defines safe removal order after root cause fix - Includes test methods for each layer removal Diagnostic Logging Enhancements (ChatGPT work): - TLS_SLL_HEAD_SET log with count and backtrace for NORMALIZE_USERPTR - tiny_next_store_log with filtering capability - Environment variables for log filtering: - HAKMEM_TINY_SLL_NEXTCLS: class filter for next store (-1 disables) - HAKMEM_TINY_SLL_NEXTTAG: tag filter (substring match) - HAKMEM_TINY_SLL_HEADCLS: class filter for head trace Current Investigation Status: - sh8bench 60/120s: crash-free, zero NEXT_INVALID/HDR_RESET/SANITIZE - BUT: shot limit (256) exhausted by class3 tls_push before class1/drain - Need: Add tags to pop/clear paths, or increase shot limit for class1 Purpose of this commit: - Document defensive layers for safe removal later - Enable targeted diagnostic logging - Prepare for final root cause identification Next Steps: 1. Add tags to tls_sll_pop tiny_next_write (e.g., "tls_pop_clear") 2. Re-run with HAKMEM_TINY_SLL_NEXTTAG=tls_pop 3. Capture class1 writes that lead to corruption 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
6.4 KiB
6.4 KiB
対処療法マッピング (2025-12-03)
目的: 根本原因が特定された後、安全に対処療法を外すための記録
現在の対処療法(5層 + 診断ログ)
Layer 1: SuperSlab Refcount Pinning
場所: core/box/tls_sll_box.h
実装:
// tls_sll_push_impl():
SuperSlab* ss = hak_super_lookup(ptr);
if (ss) atomic_fetch_add(&ss->refcount, 1); // PIN
// tls_sll_pop_impl():
SuperSlab* ss = hak_super_lookup(ptr);
if (ss) atomic_fetch_sub(&ss->refcount, 1); // UNPIN
目的: TLS SLL がポイントしてる SuperSlab が解放されるのを防ぐ
隠蔽される症状:
- Use-After-Free(SuperSlab が free された後のアクセス)
- [TLS_SLL_HDR_RESET] の一部
削除時のリスク:
- SuperSlab が参照中に解放される
- SIGSEGV の再発
テスト方法:
- Layer 1 を無効化 → sh8bench 60秒
- [TLS_SLL_HDR_RESET] / SIGSEGV が発生するか確認
Layer 2: SuperSlab Release Guards
場所:
core/superslab_allocate.c(superslab_free)core/hakmem_shared_pool_release.c(shared_pool_release_slab)core/box/ss_allocation_box.c
実装:
// superslab_free():
if (ss->refcount > 0) {
return; // DEFER - do not free
}
目的: refcount > 0 の SuperSlab を解放しない
隠蔽される症状:
- class_map が 255 (UNASSIGNED) になる
- meta_cls=255 ログ
削除時のリスク:
- class_map が書き換わる
- TLS SLL の class_idx ミスマッチ
テスト方法:
- Layer 2 を無効化 → sh8bench 60秒
- [TLS_SLL_NEXT_INVALID] + meta_cls=255 が増えるか確認
Layer 3: TLS SLL Next Pointer Validation
場所: core/box/tls_sll_box.h
実装:
// tls_sll_pop_impl() での next pointer traversal:
if (!is_valid_pointer(next)) {
fprintf(stderr, "[TLS_SLL_NEXT_INVALID] ...");
g_tls_sll[class_idx].head = NULL; // DROP
}
目的: 無効な next ポインタを検知して早期にリストを DROP
隠蔽される症状:
- Freelist corruption
- 次ポインタが別領域を指す
削除時のリスク:
- 無効なポインタが dereference される
- SIGSEGV
テスト方法:
- Layer 3 を無効化 → sh8bench 60秒
- SIGSEGV が発生するか確認
Layer 4: Unified Cache Freelist Validation
場所: core/front/tiny_unified_cache.c
実装:
// unified_cache_refill():
if (!is_valid_slab(head)) {
fprintf(stderr, "[UNIFIED_FREELIST_INVALID] ...");
freelist[i] = NULL; // DROP
}
目的: 無効な freelist head を検知して DROP
隠蔽される症状:
- freelist が別スラブを指す
- スラブ境界を越えたリンク
削除時のリスク:
- 不正なブロックが割り当てられる
- メモリ破壊
テスト方法:
- Layer 4 を無効化 → sh8bench 60秒
- [UNIFIED_FREELIST_INVALID] が増えるか確認
Layer 5: Early Decrement Fix
場所: core/tiny_free_fast.inc.h
実装:
// 削除された行:
// ss_active_dec_one(ss); // 高速パスでの早期デクリメント
目的: refcount の過剰デクリメントを防止
隠蔽される症状:
- refcount が 0 に早く落ちすぎる
- Layer 1/2 のガードが効かなくなる
削除時のリスク:
- Layer 1/2 の効果が無効化される
テスト方法:
- 早期デクリメントを復元 → sh8bench 60秒
- refcount が早く 0 になり、SIGSEGV が発生するか確認
診断ログ追加
場所: core/box/tls_sll_box.h, 各所
追加されたログ:
[TLS_SLL_HEAD_SET]- head 設定時のトレース[TLS_SLL_NEXT_INVALID]- 無効な next ポインタ検知[UNIFIED_FREELIST_INVALID]- freelist head 無効[TLS_SLL_NORMALIZE_USERPTR]- userptr の正規化[TLS_SLL_SANITIZE]- head の検証と修復[TINY_NEXT_STORE]- next ポインタ書き込みのトレース
フィルタ環境変数:
HAKMEM_TINY_SLL_NEXTCLS- next store のクラスフィルタ (-1 で無効)HAKMEM_TINY_SLL_NEXTTAG- next store のタグフィルタ (部分一致)HAKMEM_TINY_SLL_HEADCLS- head trace のクラスフィルタ
根本修正後の削除順序(推奨)
Phase 1: 診断ログを維持しながら確認
- 根本修正を適用
- sh8bench 60秒テスト
- 診断ログがゼロになることを確認
Phase 2: Validation layers (Layer 3/4) を削除
- Layer 3 (next validation) を無効化
- sh8bench 60秒テスト
- [TLS_SLL_NEXT_INVALID] がゼロ(本当に発生しない)ことを確認
- Layer 4 (freelist validation) を無効化
- sh8bench 60秒テスト
- 問題がないことを確認
Phase 3: Refcount layers (Layer 1/2) を削除
- Layer 2 (release guards) を無効化
- sh8bench 60秒テスト
- class_map が正常に動作することを確認
- Layer 1 (refcount pinning) を無効化
- sh8bench 60秒テスト
- SuperSlab lifecycle が正常であることを確認
Phase 4: 診断ログを削除
- ショット制限を復元(または ENV で無効化)
- パフォーマンステスト
- オーバーヘッドがないことを確認
削除チェックリスト
| Layer | ファイル | 行 | 削除方法 | テスト |
|---|---|---|---|---|
| 1 | tls_sll_box.h | push/pop | atomic_fetch_add/sub を削除 | sh8bench 60s |
| 2 | superslab_allocate.c | superslab_free | if (refcount>0) return を削除 | sh8bench 60s |
| 2 | shared_pool_release.c | release_slab | 同上 | sh8bench 60s |
| 2 | ss_allocation_box.c | 各所 | 同上 | sh8bench 60s |
| 3 | tls_sll_box.h | pop | validation + DROP を削除 | sh8bench 60s |
| 4 | tiny_unified_cache.c | refill | validation + DROP を削除 | sh8bench 60s |
| 5 | tiny_free_fast.inc.h | - | 既に削除済み(復元しない) | - |
注意事項
- 一度に全部外さない - 1層ずつ外してテスト
- ログは最後に外す - 問題が再発したら診断できるように
- テストは複数回 - タイミング依存の問題がある可能性
- メモリ監視も継続 - RSS が増加しないことを確認
関連ドキュメント
docs/ANALYSIS_SYMPTOM_PROLIFERATION.md- 対処療法の分析docs/BREAKTHROUGH_STABILITY_ACHIEVED.md- 安定性達成の報告docs/CRITICAL_DISCOVERY_TLS_HEAD_CORRUPTION.md- TLS head 汚染の発見
Document created: 2025-12-03 Purpose: Enable safe removal of defensive layers after root cause fix