273 lines
6.4 KiB
Markdown
273 lines
6.4 KiB
Markdown
|
|
# Segmentation Fault 調査指示書 for Gemini
|
|||
|
|
|
|||
|
|
Version: 1.0 (2025-12-03)
|
|||
|
|
Status: Phase 2 Headerless 実装中に segfault 発生
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔍 現状
|
|||
|
|
|
|||
|
|
### ビルド状況
|
|||
|
|
|
|||
|
|
- ✅ **ビルド成功**: `libhakmem.so` が正常に生成される
|
|||
|
|
- ✅ インクルード順序エラー解決済み
|
|||
|
|
- ⚠️ **実行時エラー**: Segmentation Fault が発生
|
|||
|
|
|
|||
|
|
### Segfault 情報
|
|||
|
|
|
|||
|
|
**報告内容**:
|
|||
|
|
- Phase 2 Headerless 実装中に segfault 発生
|
|||
|
|
- ビルドは通るが実行時にクラッシュ
|
|||
|
|
- 詳細なエラーメッセージは未報告
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 調査目標
|
|||
|
|
|
|||
|
|
1. **Segfault が発生する正確な条件を特定**
|
|||
|
|
2. **どのコンポーネントが原因か判定**
|
|||
|
|
3. **修正パッチを提案**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📋 調査手順
|
|||
|
|
|
|||
|
|
### Step 1: デバッグビルド& GDB での実行
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /mnt/workdisk/public_share/hakmem
|
|||
|
|
|
|||
|
|
# クリーンビルド(デバッグシンボル付き)
|
|||
|
|
find . -name "*.o" -delete
|
|||
|
|
make clean
|
|||
|
|
make shared -j8 EXTRA_CFLAGS="-g -O1"
|
|||
|
|
|
|||
|
|
# GDB で実行
|
|||
|
|
gdb --args ./mimalloc-bench/out/bench/sh8bench
|
|||
|
|
|
|||
|
|
# GDB 内:
|
|||
|
|
(gdb) run
|
|||
|
|
# → Segfault が発生したら:
|
|||
|
|
(gdb) backtrace
|
|||
|
|
(gdb) frame 0
|
|||
|
|
(gdb) info locals
|
|||
|
|
(gdb) disassemble
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Step 2: ASan(AddressSanitizer)での検証
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# ASan ビルド
|
|||
|
|
make clean
|
|||
|
|
make asan-shared-alloc -j8
|
|||
|
|
|
|||
|
|
# ASan 実行(詳細なエラー情報が出力される)
|
|||
|
|
LD_PRELOAD=./libhakmem_asan.so ./mimalloc-bench/out/bench/sh8bench 2>&1 | head -100
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**ASan が出力する情報**:
|
|||
|
|
- どのアドレスでクラッシュしたか
|
|||
|
|
- どの関数で発生したか
|
|||
|
|
- メモリ破壊の詳細
|
|||
|
|
|
|||
|
|
### Step 3: 最小限のテストプログラム作成
|
|||
|
|
|
|||
|
|
Segfault が頻繁に発生する場合、最小限のテストプログラムを作成して確認:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
// tests/test_segfault_minimal.c
|
|||
|
|
|
|||
|
|
#include <stdio.h>
|
|||
|
|
#include <stdlib.h>
|
|||
|
|
#include "../core/hakmem.h"
|
|||
|
|
|
|||
|
|
int main() {
|
|||
|
|
printf("Test 1: Simple malloc\n");
|
|||
|
|
void* ptr1 = malloc(15);
|
|||
|
|
printf(" malloc(15) = %p\n", ptr1);
|
|||
|
|
|
|||
|
|
printf("Test 2: Simple free\n");
|
|||
|
|
free(ptr1);
|
|||
|
|
printf(" free() succeeded\n");
|
|||
|
|
|
|||
|
|
printf("Test 3: Multiple allocations\n");
|
|||
|
|
for (int i = 0; i < 100; i++) {
|
|||
|
|
void* p = malloc(15);
|
|||
|
|
free(p);
|
|||
|
|
}
|
|||
|
|
printf(" 100 alloc/free cycles succeeded\n");
|
|||
|
|
|
|||
|
|
printf("Test 4: Concurrent-like pattern\n");
|
|||
|
|
void* ptrs[10];
|
|||
|
|
for (int i = 0; i < 10; i++) {
|
|||
|
|
ptrs[i] = malloc(15 + i);
|
|||
|
|
}
|
|||
|
|
for (int i = 0; i < 10; i++) {
|
|||
|
|
free(ptrs[i]);
|
|||
|
|
}
|
|||
|
|
printf(" Concurrent pattern succeeded\n");
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Step 4: Headerless フラグの確認
|
|||
|
|
|
|||
|
|
Headerless モード(Phase 2)での動作確認:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Headerless OFF(Phase 1 互換)
|
|||
|
|
make clean
|
|||
|
|
make shared -j8
|
|||
|
|
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench 2>&1 | grep -E "error|Segmentation|Total"
|
|||
|
|
|
|||
|
|
# Headerless ON(Phase 2)
|
|||
|
|
make clean
|
|||
|
|
make shared -j8 EXTRA_CFLAGS="-DHAKMEM_TINY_HEADERLESS=1"
|
|||
|
|
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench 2>&1 | grep -E "error|Segmentation|Total"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**確認項目**:
|
|||
|
|
- [ ] Headerless OFF で segfault が出ないか
|
|||
|
|
- [ ] Headerless ON で segfault が出るか
|
|||
|
|
- [ ] Phase 1 と Phase 2 のどちらの問題か判定
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🔧 よくある Segfault 原因と確認方法
|
|||
|
|
|
|||
|
|
### 原因1: Use-After-Free
|
|||
|
|
|
|||
|
|
**兆候**:
|
|||
|
|
- Free 後のポインタアクセス
|
|||
|
|
- GDB: `backtrace` に free → access の順序が見える
|
|||
|
|
|
|||
|
|
**確認コマンド**:
|
|||
|
|
```bash
|
|||
|
|
# ASan で USE_AFTER_FREE エラーが報告される
|
|||
|
|
LD_PRELOAD=./libhakmem_asan.so ./test 2>&1 | grep -i "use.*after.*free"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 原因2: Buffer Overflow
|
|||
|
|
|
|||
|
|
**兆候**:
|
|||
|
|
- 配列境界外アクセス
|
|||
|
|
- 隣接メモリの破壊
|
|||
|
|
|
|||
|
|
**確認コマンド**:
|
|||
|
|
```bash
|
|||
|
|
# ASan で BUFFER_OVERFLOW エラーが報告される
|
|||
|
|
LD_PRELOAD=./libhakmem_asan.so ./test 2>&1 | grep -i "buffer\|overflow"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 原因3: NULL ポインタデリファレンス
|
|||
|
|
|
|||
|
|
**兆候**:
|
|||
|
|
- `malloc()` が NULL を返す
|
|||
|
|
- NULL チェックなしでアクセス
|
|||
|
|
|
|||
|
|
**確認コマンド**:
|
|||
|
|
```bash
|
|||
|
|
# GDB で frame 0 の命令が NULL の dereference か確認
|
|||
|
|
(gdb) disassemble
|
|||
|
|
# → 「mov $0x0」「dereference」のパターン
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 原因4: メモリリーク → ヒープ枯渇
|
|||
|
|
|
|||
|
|
**兆候**:
|
|||
|
|
- 長時間実行でメモリ使用量が増加
|
|||
|
|
- やがてメモリ割り当て失敗 → segfault
|
|||
|
|
|
|||
|
|
**確認コマンド**:
|
|||
|
|
```bash
|
|||
|
|
# メモリ使用量を監視しながら実行
|
|||
|
|
( while true; do ps aux | grep sh8bench | grep -v grep | awk '{print $6}'; sleep 1; done ) &
|
|||
|
|
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 調査報告形式
|
|||
|
|
|
|||
|
|
Segfault の調査が完了したら、以下の形式で報告してください:
|
|||
|
|
|
|||
|
|
```markdown
|
|||
|
|
## Segfault 調査結果
|
|||
|
|
|
|||
|
|
### 環境
|
|||
|
|
- ビルドオプション: [e.g., "-DHAKMEM_TINY_HEADERLESS=1"]
|
|||
|
|
- テスト内容: [e.g., "sh8bench"]
|
|||
|
|
|
|||
|
|
### GDB 情報
|
|||
|
|
\`\`\`
|
|||
|
|
(gdb) backtrace
|
|||
|
|
#0 0x... in function_name ()
|
|||
|
|
#1 0x... in caller_function ()
|
|||
|
|
...
|
|||
|
|
|
|||
|
|
(gdb) frame 0
|
|||
|
|
#0 address in function_name ()
|
|||
|
|
at file.c:123
|
|||
|
|
\`\`\`
|
|||
|
|
|
|||
|
|
### ASan 出力
|
|||
|
|
[ASan error output if available]
|
|||
|
|
|
|||
|
|
### 根本原因
|
|||
|
|
[Your analysis of the root cause]
|
|||
|
|
|
|||
|
|
### 修正案
|
|||
|
|
[Proposed fix]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 実装フロー
|
|||
|
|
|
|||
|
|
**推奨手順**:
|
|||
|
|
|
|||
|
|
1. **Step 1-2 実行**: GDB + ASan で問題を特定
|
|||
|
|
2. **Step 3 実行**: 最小限テストプログラムで再現
|
|||
|
|
3. **Step 4 実行**: Headerless ON/OFF の判定
|
|||
|
|
4. **修正提案**: 原因に基づいた修正をコード提示
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📚 参考資料
|
|||
|
|
|
|||
|
|
### これまでのドキュメント
|
|||
|
|
- `docs/REFACTOR_PLAN_GEMINI_ENHANCED.md` - 全体計画
|
|||
|
|
- `docs/PHASE2_HEADERLESS_INSTRUCTION_FOR_GEMINI.md` - Phase 2 実装指示
|
|||
|
|
- `docs/tls_sll_hdr_reset_final_report.md` - Phase 2 の背景
|
|||
|
|
|
|||
|
|
### デバッグツール
|
|||
|
|
- GDB: `gdb --args ./program`
|
|||
|
|
- ASan: `make asan-shared-alloc`
|
|||
|
|
- Valgrind: `valgrind --leak-check=full ./program`
|
|||
|
|
|
|||
|
|
### 既知の課題
|
|||
|
|
- TLS_SLL_HDR_RESET は Phase 2 で解決予定
|
|||
|
|
- Headerless モード実装中のため、不安定な可能性あり
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 💡 ヒント
|
|||
|
|
|
|||
|
|
1. **頻繁に segfault が発生する場合**:
|
|||
|
|
- 最小限テストプログラムを使用して条件を狭める
|
|||
|
|
- GDB で `run` → `backtrace` → `frame 0` の順で実行
|
|||
|
|
|
|||
|
|
2. **ASan のエラーメッセージが出ない場合**:
|
|||
|
|
- ASan が検出できない微妙なメモリ破壊の可能性
|
|||
|
|
- GDB で manual inspection
|
|||
|
|
|
|||
|
|
3. **Headerless モードが原因の場合**:
|
|||
|
|
- Phase 2 指示書の Task 2.1-2.7 を見直す
|
|||
|
|
- 特に Task 2.4(Free パスの class_idx 取得)が怪しい
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
Gemini の調査力に期待しています!
|
|||
|
|
根本原因の特定と修正パッチの提案をお願いします。🚀
|