# バッチ設計書 15-build_symbolizer.sh

## 概要

本ドキュメントは、Sanitizerランタイム用のシンボライザーオブジェクトファイルを生成する `build_symbolizer.sh` バッチの設計仕様を定義するものである。

### 本バッチの処理概要

このバッチは、Sanitizerランタイムがインプロセスでコード/データをシンボル化するために使用する自己完結型オブジェクトファイルを生成する。zlib、libc++/libc++abi、LLVMのシンボル化ライブラリをビルドし、単一のオブジェクトファイルにリンクする。

**業務上の目的・背景**：AddressSanitizer（ASan）、ThreadSanitizer（TSan）等のSanitizerツールは、メモリエラーやデータ競合を検出した際にスタックトレースを表示する。このスタックトレースをシンボル名（関数名、ファイル名、行番号）で表示するために、シンボライザーが必要となる。本バッチは、外部プロセスを起動せずにインプロセスでシンボル化を行うための静的リンク可能なオブジェクトファイルを生成する。

**バッチの実行タイミング**：Sanitizerランタイムのビルド時、またはシンボライザーの更新が必要な場合に実行される。

**主要な処理内容**：
1. zlibのダウンロード/ビルド（圧縮デバッグ情報の展開用）
2. libc++/libc++abiのビルドとインストール
3. LLVMシンボル化関連ライブラリのビルド
4. sanitizer_symbolize.cpp/sanitizer_wrappers.cppのコンパイル
5. 全ライブラリのLLVMビットコードへのリンク
6. 内部化最適化（公開API以外を非公開化）
7. オブジェクトファイルへの変換
8. 未定義シンボルの検証

**前後の処理との関連**：生成されたsymbolizer.oはSanitizerランタイムのビルドに組み込まれる。

**影響範囲**：Sanitizerランタイムのシンボル化機能に影響。デバッグ情報の表示品質に直結する。

## バッチ種別

ビルド処理 / ライブラリ生成

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時 |
| 実行時刻 | 任意 |
| 実行曜日 | 任意 |
| 実行日 | 任意 |
| トリガー | 手動実行 / Sanitizerビルドプロセス |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Clangコンパイラ | clang/clang++が利用可能であること |
| LLVMツール | llvm-tblgen, llvm-ar, llvm-link, optが利用可能であること |
| CMake/Ninja | ビルドシステムが利用可能であること |
| Git | zlibのクローン用（ZLIB_SRC未指定時） |
| ネットワーク接続 | zlib取得時に必要（ZLIB_SRC未指定時） |

### 実行可否判定

- CLANG環境変数または which clang でコンパイラが見つかること
- 必要なLLVMツールがすべて存在すること

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| $1 (出力ファイル) | string | Yes | なし | 出力オブジェクトファイルのパス |
| CLANG | 環境変数 | No | which clang | Clangコンパイラのパス |
| ZLIB_SRC | 環境変数 | No | なし（GitHub取得） | zlibソースディレクトリ |
| FLAGS | 環境変数 | No | 空 | 追加コンパイルフラグ |
| LLVM_SRC | 環境変数 | No | 自動検出 | LLVMソースディレクトリ |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| sanitizer_symbolize.cpp | C++ Source | シンボライザーメインソース |
| sanitizer_wrappers.cpp | C++ Source | ラッパー関数 |
| https://github.com/madler/zlib | Git Repository | zlib圧縮ライブラリ |
| LLVM_SRC/runtimes | Directory | libc++/libc++abiソース |
| LLVM_SRC | Directory | LLVMソース |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| $1 (引数指定) | Object File | シンボライザーオブジェクトファイル |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 引数で指定 |
| 出力先 | 引数で指定されたパス |
| 文字コード | バイナリ |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. 環境設定
   └─ CLANG, 各種ツールパスの設定
2. ツール存在チェック
   └─ clang, clang++, llvm-tblgen, opt, llvm-ar, llvm-linkの存在確認
3. zlibビルド
   └─ ソース取得（Git or ローカル）→ configure → make
4. libc++/libc++abiビルド
   └─ CMake設定 → Ninjaビルド → インストール
5. LLVMライブラリビルド
   └─ CMake設定 → Ninjaビルド（複数ターゲット）
6. シンボライザーソースコンパイル
   └─ sanitizer_symbolize.cpp, sanitizer_wrappers.cpp
7. ライブラリ統合
   └─ llvm-linkで全ライブラリをall.bcに統合
8. 最適化
   └─ optで内部化（internalizeパス）
9. オブジェクトファイル生成
   └─ clangでopt.bc → symbolizer.o
10. シンボル検証
    └─ nmで未定義シンボルをglobal_symbols.txtと比較
11. 出力コピー
    └─ symbolizer.oを指定パスにコピー
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[引数チェック]
    B --> C{出力ファイル指定?}
    C -->|No| D[エラー終了]
    C -->|Yes| E[ツール存在チェック]
    E --> F{全ツール存在?}
    F -->|No| G[エラー終了]
    F -->|Yes| H[zlibビルド]
    H --> I[libc++/libc++abiビルド]
    I --> J[LLVMライブラリビルド]
    J --> K[シンボライザーソースコンパイル]
    K --> L[llvm-link: 全ライブラリ統合]
    L --> M[opt: 内部化最適化]
    M --> N[clang: オブジェクトファイル生成]
    N --> O[nm: シンボル検証]
    O --> P{想定外シンボル?}
    P -->|Yes| Q[エラー終了]
    P -->|No| R[出力ファイルコピー]
    R --> S[Success出力]
    S --> T[バッチ終了]
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチはデータベース操作を行わない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

### テーブル別操作詳細

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 引数エラー | 出力ファイル未指定 | 出力ファイルパスを指定 |
| 1 | ツール不足 | 必要なツールが存在しない | CLANGパスを確認、LLVMツールをインストール |
| 1 | シンボルエラー | 想定外のシンボルが存在 | ソースコードを確認、global_symbols.txtを更新 |
| 非0 | ビルドエラー | 各種ビルド失敗 | ログを確認 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（自動リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. `set -e` によりエラー発生時は即座にスクリプト終了
2. ビルドディレクトリ（$PWD/symbolizer）を削除して再実行
3. 各ビルド段階のログを確認

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（ファイルシステム操作のみ） |
| コミットタイミング | N/A |
| ロールバック条件 | エラー時は手動でクリーンアップ |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1ビルド |
| 目標処理時間 | 10-30分（ネットワーク速度、CPUコア数依存） |
| メモリ使用量上限 | LLVMビルド依存（数GB） |

## 排他制御

ビルドディレクトリ（$PWD/symbolizer）を使用するため、同一ディレクトリでの複数実行は競合する。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | 各ステージ | "Compiling...", "Optimizing...", "Checking undefined symbols..." |
| 終了ログ | 成功時 | "Success!" |
| エラーログ | エラー発生時 | "Missing $F", "Missing output file", "Failed: unexpected symbols" |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| 終了コード | 非0 | 手動確認 |
| 処理時間 | 60分超過 | 手動確認 |

## 備考

- 本スクリプトは `compiler-rt/lib/sanitizer_common/symbolizer/scripts/` に配置される
- ソースコードの場所: `compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh`
- 公開API: `__sanitizer_symbolize_code`, `__sanitizer_symbolize_data`, `__sanitizer_symbolize_frame`, `__sanitizer_symbolize_flush`, `__sanitizer_symbolize_demangle`, `__sanitizer_symbolize_set_demangle`, `__sanitizer_symbolize_set_inline_frames`
- LTOビルド（-flto）でサイズ最適化
- `set -x -e -u` でデバッグ出力とエラー時終了を有効化
- global_symbols.txtで許可されたシンボルを管理
