240 lines
6.4 KiB
Markdown
240 lines
6.4 KiB
Markdown
|
|
# 対処療法マッピング (2025-12-03)
|
|||
|
|
|
|||
|
|
**目的**: 根本原因が特定された後、安全に対処療法を外すための記録
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 現在の対処療法(5層 + 診断ログ)
|
|||
|
|
|
|||
|
|
### Layer 1: SuperSlab Refcount Pinning
|
|||
|
|
|
|||
|
|
**場所**: `core/box/tls_sll_box.h`
|
|||
|
|
|
|||
|
|
**実装**:
|
|||
|
|
```c
|
|||
|
|
// 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`
|
|||
|
|
|
|||
|
|
**実装**:
|
|||
|
|
```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`
|
|||
|
|
|
|||
|
|
**実装**:
|
|||
|
|
```c
|
|||
|
|
// 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`
|
|||
|
|
|
|||
|
|
**実装**:
|
|||
|
|
```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`
|
|||
|
|
|
|||
|
|
**実装**:
|
|||
|
|
```c
|
|||
|
|
// 削除された行:
|
|||
|
|
// 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: 診断ログを維持しながら確認
|
|||
|
|
|
|||
|
|
1. 根本修正を適用
|
|||
|
|
2. sh8bench 60秒テスト
|
|||
|
|
3. 診断ログが**ゼロ**になることを確認
|
|||
|
|
|
|||
|
|
### Phase 2: Validation layers (Layer 3/4) を削除
|
|||
|
|
|
|||
|
|
1. Layer 3 (next validation) を無効化
|
|||
|
|
2. sh8bench 60秒テスト
|
|||
|
|
3. [TLS_SLL_NEXT_INVALID] がゼロ(本当に発生しない)ことを確認
|
|||
|
|
4. Layer 4 (freelist validation) を無効化
|
|||
|
|
5. sh8bench 60秒テスト
|
|||
|
|
6. 問題がないことを確認
|
|||
|
|
|
|||
|
|
### Phase 3: Refcount layers (Layer 1/2) を削除
|
|||
|
|
|
|||
|
|
1. Layer 2 (release guards) を無効化
|
|||
|
|
2. sh8bench 60秒テスト
|
|||
|
|
3. class_map が正常に動作することを確認
|
|||
|
|
4. Layer 1 (refcount pinning) を無効化
|
|||
|
|
5. sh8bench 60秒テスト
|
|||
|
|
6. SuperSlab lifecycle が正常であることを確認
|
|||
|
|
|
|||
|
|
### Phase 4: 診断ログを削除
|
|||
|
|
|
|||
|
|
1. ショット制限を復元(または ENV で無効化)
|
|||
|
|
2. パフォーマンステスト
|
|||
|
|
3. オーバーヘッドがないことを確認
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 削除チェックリスト
|
|||
|
|
|
|||
|
|
| 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. **一度に全部外さない** - 1層ずつ外してテスト
|
|||
|
|
2. **ログは最後に外す** - 問題が再発したら診断できるように
|
|||
|
|
3. **テストは複数回** - タイミング依存の問題がある可能性
|
|||
|
|
4. **メモリ監視も継続** - 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*
|