根治修正: unified_cache_refill SEGVAULT + コンパイラ最適化対策

問題:
  - リリース版sh8benchでunified_cache_refill+0x46fでSEGVAULT
  - コンパイラ最適化により、ヘッダー書き込みとtiny_next_read()の
    順序が入れ替わり、破損したポインタをout[]に格納

根本原因:
  - ヘッダー書き込みがtiny_next_read()の後にあった
  - volatile barrierがなく、コンパイラが自由に順序を変更
  - ASan版では最適化が制限されるため問題が隠蔽されていた

修正内容(P1-P3):

P1: unified_cache_refill SEGVAULT修正 (core/front/tiny_unified_cache.c:341-350)
  - ヘッダー書き込みをtiny_next_read()の前に移動
  - __atomic_thread_fence(__ATOMIC_RELEASE)追加
  - コンパイラ最適化による順序入れ替えを防止

P2: 二重書き込み削除 (core/box/tiny_front_cold_box.h:75-82)
  - tiny_region_id_write_header()削除
  - unified_cache_refillが既にヘッダー書き込み済み
  - 不要なメモリ操作を削除して効率化

P3: tiny_next_read()安全性強化 (core/tiny_nextptr.h:73-86)
  - __atomic_thread_fence(__ATOMIC_ACQUIRE)追加
  - メモリ操作の順序を保証

P4: ヘッダー書き込みデフォルトON (core/tiny_region_id.h - ChatGPT修正)
  - g_write_headerのデフォルトを1に変更
  - HAKMEM_TINY_WRITE_HEADER=0で旧挙動に戻せる

テスト結果:
   unified_cache_refill SEGVAULT: 解消(sh8bench実行可能に)
   TLS_SLL_HDR_RESET: まだ発生中(別の根本原因、調査継続)

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm (CI)
2025-12-03 09:57:12 +09:00
parent 4cc2d8addf
commit 6154e7656c
4 changed files with 28 additions and 14 deletions

View File

@ -238,16 +238,16 @@ static inline void* tiny_region_id_write_header(void* base, int class_idx) {
} while (0);
#endif // !HAKMEM_BUILD_RELEASE
// P3: Skip header write when class_map is active (default)
// class_map provides class_idx lookup, so header byte is no longer needed
// ENV: HAKMEM_TINY_WRITE_HEADER=1 to force header write (legacy mode)
// Memory layout preserved: user = base + 1 (1B unused when skipped)
// P3: Header writeをデフォルトONTLS SLL向けに常時復元、ENVでOFF可能
// class_map があっても TLS SLL 境界でヘッダーが必要になるため、A/B 切替は
// HAKMEM_TINY_WRITE_HEADER=0 でのみ OFF旧デフォルトにする。
// Memory layout preserved: user = base + 1(ヘッダー領域は常に予約)
static int g_write_header = -1;
if (__builtin_expect(g_write_header == -1, 0)) {
const char* e = getenv("HAKMEM_TINY_WRITE_HEADER");
g_write_header = (e && *e && *e != '0') ? 1 : 0;
g_write_header = (e && *e && *e == '0') ? 0 : 1;
}
if (__builtin_expect(g_write_header, 0)) {
if (__builtin_expect(g_write_header, 1)) {
// Legacy mode: write header for debugging or compatibility
*header_ptr = HEADER_MAGIC | (class_idx & HEADER_CLASS_MASK);
PTR_TRACK_HEADER_WRITE(base, HEADER_MAGIC | (class_idx & HEADER_CLASS_MASK));