# 帳票設計書 15-crashinfo - OSコアダンプ解析レポート

## 概要

本ドキュメントは、FreeBSD の `crashinfo` コマンドが出力するOSコアダンプ解析レポートの設計仕様を記述する。

### 本帳票の処理概要

crashinfo は、カーネルクラッシュダンプ（vmcore）を解析し、システム障害の診断に必要な情報を包括的にまとめたレポートを生成するシェルスクリプトである。GDB/KGDBを使用したスタックトレースと、各種システムユーティリティの出力を統合する。

**業務上の目的・背景**：カーネルパニック等のシステム障害発生時に、障害原因の特定と分析に必要な情報を一元的に収集するために使用される。クラッシュダンプファイルからカーネルの状態情報を自動的に抽出し、構造化されたレポートとして保存することで、障害分析の効率化と情報の散逸防止を実現する。

**帳票の利用シーン**：カーネルパニック後のクラッシュダンプ解析、システム障害の根本原因分析（RCA）、開発者へのバグレポート作成、障害対応記録の保存などの場面で利用される。

**主要な出力内容**：
1. システム情報（ホスト名、OS情報、パニック文字列）
2. カーネルバックトレース（bt -full）と全スレッドトレース（acttrace）
3. プロセス一覧（ps -axlww）
4. 仮想メモリ統計（vmstat -s/-m/-z/-i）
5. pstat情報（-T, -s）
6. I/O統計（iostat）
7. IPC情報（ipcs -a/-T）
8. ネットワーク統計（netstat -s/-m/-anA/-aL）
9. fstat、dmesg、カーネルコンフィグ、DDBキャプチャバッファ

**帳票の出力タイミング**：管理者がコマンドラインから `crashinfo` コマンドを実行した際、またはバッチモード（-b）で自動実行された際にファイルに出力される。

**帳票の利用者**：カーネル開発者、システム管理者、障害対応チーム

## 帳票種別

集計表（クラッシュダンプ診断レポート）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| N/A | コマンドラインインターフェース | N/A | `crashinfo` コマンド実行 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト |
| 用紙サイズ | N/A |
| 向き | N/A |
| ファイル名 | core.txt.{DUMPNR}（例: core.txt.0） |
| 出力方法 | ファイル出力（$CRASHDIR/core.txt.$DUMPNR） |
| 文字コード | ロケール依存 |

## 帳票レイアウト

### レイアウト概要

複数のセクションがセパレータ行（"--------..."）で区切られたテキストレポート。

```
┌──────────────────────────────────────────────────────────────┐
│ {hostname} dumped core - see {vmcore path}                    │
│ {date}                                                        │
│ {OS type} {hostname} {release} {version} {machine}           │
│ panic: {panic string}                                         │
├──────────────────────────────────────────────────────────────┤
│ kgdb bt -full / acttrace 出力                                 │
├──────────────────────────────────────────────────────────────┤
│ ps -axlww                                                     │
├──────────────────────────────────────────────────────────────┤
│ vmstat -s / vmstat -m / vmstat -z / vmstat -i                 │
├──────────────────────────────────────────────────────────────┤
│ pstat -T / pstat -s                                           │
├──────────────────────────────────────────────────────────────┤
│ iostat                                                        │
├──────────────────────────────────────────────────────────────┤
│ ipcs -a / ipcs -T                                             │
├──────────────────────────────────────────────────────────────┤
│ netstat -s / netstat -m / netstat -anA / netstat -aL          │
├──────────────────────────────────────────────────────────────┤
│ fstat / dmesg / kernel config / ddb capture buffer            │
└──────────────────────────────────────────────────────────────┘
```

### ヘッダー部

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | ダンプ通知 | ホスト名とvmcoreパス | hostname, VMCORE変数 | "{hostname} dumped core - see {vmcore}" |
| 2 | 日付 | レポート生成日時 | date コマンド | 標準日時形式 |
| 3 | システム識別 | OS種別・リリース・バージョン・アーキテクチャ | GDBによるカーネルシンボル読取り | "{ostype} {hostname} {osrelease} {version} {machine}" |
| 4 | パニック文字列 | カーネルパニックの原因メッセージ | info.{DUMPNR} ファイルのPanic String行 | "panic: {string}" |

### 明細部（各セクション）

| No | セクション名 | コマンド | データ取得元 | 説明 |
|----|------------|--------|-------------|------|
| 1 | カーネルバックトレース | kgdb (bt -full, acttrace) | vmcore + kernel | フルバックトレースと全アクティブスレッドのトレース |
| 2 | プロセス一覧 | ps -M -N -axlww | vmcore + kernel | クラッシュ時の全プロセス詳細 |
| 3 | VM統計サマリー | vmstat -M -N -s | vmcore + kernel | 仮想メモリ統計サマリー |
| 4 | メモリアロケータ統計 | vmstat -M -N -m | vmcore + kernel | malloc型別統計 |
| 5 | UMAゾーン統計 | vmstat -M -N -z | vmcore + kernel | UMAゾーン別統計 |
| 6 | 割り込み統計 | vmstat -M -N -i | vmcore + kernel | 割り込みカウンタ |
| 7 | 資源テーブル | pstat -M -N -T | vmcore + kernel | カーネル資源テーブル |
| 8 | スワップ統計 | pstat -M -N -s | vmcore + kernel | スワップデバイス統計 |
| 9 | I/O統計 | iostat -M -N | vmcore + kernel | ディスクI/O統計 |
| 10 | IPC施設 | ipcs -C -N -a | vmcore + kernel | System V IPC詳細 |
| 11 | IPC統計 | ipcs -C -N -T | vmcore + kernel | System V IPC統計 |
| 12 | ネットワーク統計 | netstat -M -N -s | vmcore + kernel | プロトコル統計 |
| 13 | mbuf統計 | netstat -M -N -m | vmcore + kernel | ネットワークメモリ統計 |
| 14 | ソケット一覧 | netstat -M -N -anA | vmcore + kernel | 全ソケット（アドレス付き） |
| 15 | リスンソケット | netstat -M -N -aL | vmcore + kernel | リッスン中ソケット |
| 16 | オープンファイル | fstat -M -N | vmcore + kernel | オープンファイル一覧 |
| 17 | カーネルメッセージ | dmesg -a -M -N | vmcore + kernel | カーネルメッセージバッファ |
| 18 | カーネルコンフィグ | config -x | kernel | カーネル設定展開 |
| 19 | DDBキャプチャ | ddb capture -M -N print | vmcore + kernel | DDBデバッガキャプチャバッファ |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| ダンプ番号 | -n オプションまたはvmcoreファイル名から | No（デフォルト: 最新） |
| カーネルファイル | -k オプションまたは自動検出 | No（自動マッチング） |
| クラッシュディレクトリ | -d オプション | No（デフォルト: /var/crash） |

### 改ページ条件

セクションごとにセパレータ行（72文字の"-"）で区切り

## データベース参照仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 結合条件 |
|-----------|------|---------|
| vmcore.{N} | クラッシュダンプ本体 | CRASHDIR/vmcore.DUMPNR |
| info.{N} | ダンプ情報ファイル | CRASHDIR/info.DUMPNR |
| kernel | カーネルバイナリ | バージョン文字列マッチング |
| bounds | 最新ダンプ番号 | CRASHDIR/bounds |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| 最新ダンプ番号 | bounds ファイルの値 - 1 | 整数 | 行140-146 |
| カーネルマッチング | info.Nのバージョン文字列とカーネルのversionシンボルを比較 | N/A | find_kernel()関数 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[crashinfoコマンド実行] --> B[オプション解析]
    B --> C[vmcore/infoファイルパス決定]
    C --> D{vmcore存在?}
    D -->|圧縮| E[gzcat/zstdcatで展開]
    D -->|存在| F[カーネルファイル検索]
    D -->|なし| Z[エラー終了]
    E --> F
    F --> G[GDBでシステム情報取得]
    G --> H[ヘッダー出力]
    H --> I[kgdbでバックトレース]
    I --> J[ps/vmstat/pstat/iostat等実行]
    J --> K[netstat/fstat/dmesg等実行]
    K --> L[config/ddb capture]
    L --> M[終了・一時ファイルクリーンアップ]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| GDB未インストール | /usr/local/bin/gdb が存在しない | "Unable to find a kernel debugger" | exit 1 |
| vmcore未発見 | vmcoreファイルが存在しない | "$VMCORE not found" | exit 1 |
| infoファイル未発見 | info.Nが存在しない | "$INFO not found" | exit 1 |
| カーネル不一致 | バージョン一致するカーネルが見つからない | "Unable to find matching kernel" | exit 1 |
| ダンプ番号不明 | boundsファイルが空またはゼロ | "No crash dumps in $CRASHDIR" | exit 1 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 1ダンプファイル（数GB〜数十GB） |
| 目標出力時間 | ダンプサイズに依存（数分〜数十分） |
| 同時出力数上限 | 1（シングルプロセス実行） |

## セキュリティ考慮事項

- vmcoreにはカーネルメモリの内容が含まれるため、パスワードハッシュ等の機密情報が含まれる可能性がある
- umask 077 で出力ファイルの権限を制限（行196）
- root権限が必要
- 出力ファイルの保管場所のアクセス制御が重要

## 備考

- シェルスクリプトで実装されている（/bin/sh）
- GDBはdevel/gdbポートまたはgdbパッケージが必要（/usr/local/bin/gdb）
- vmcoreの圧縮形式として .gz と .zst をサポート（行167-176）
- find_kernel()でカーネルバージョン文字列のマッチングを行い、適切なカーネルファイルを自動検出（行59-88）
- 各種ユーティリティに -M（コアファイル指定）と -N（カーネル指定）オプションを付けて実行

---

## コードリーディングガイド

本帳票を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: スクリプト全体構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | crashinfo.sh | `usr.sbin/crashinfo/crashinfo.sh` | スクリプト全体（345行）、主要変数（VMCORE, INFO, FILE, KERNEL）の役割 |

**読解のコツ**: シェルスクリプトのため、上から下へ順に読むことで処理フローを把握できる。

#### Step 2: 初期化・カーネル検索を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | crashinfo.sh | `usr.sbin/crashinfo/crashinfo.sh` | usage()（行33-38）、find_kernel()（行59-88）、オプション解析（行95-113）、ダンプ番号決定（行117-147） |

**主要処理フロー**:
1. **行90-93**: 変数初期化（BATCH=false, CRASHDIR=/var/crash）
2. **行95-113**: getoptsによるオプション解析（-b, -d, -n, -k）
3. **行117-147**: 引数またはboundsファイルからダンプ番号決定
4. **行149-152**: パス変数設定（VMCORE, INFO, FILE, HOSTNAME）
5. **行159-164**: GDB存在確認
6. **行166-177**: vmcore圧縮形式の自動検出・展開
7. **行185-194**: カーネルファイルの検索（find_kernel）またはユーザー指定

#### Step 3: レポート出力セクションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | crashinfo.sh | `usr.sbin/crashinfo/crashinfo.sh` | GDBによるシステム情報取得（行199-203）、kgdbバックトレース（行218-226）、各種ユーティリティ呼出し（行229-345） |

**主要処理フロー**:
- **行199-203**: gdb_command()でostype/osrelease/version/machine取得
- **行218-226**: kgdbで "bt -full", "acttrace", "quit" を実行
- **行229-345**: ps, vmstat, pstat, iostat, ipcs, netstat, fstat, dmesg, config, ddb を順次実行

### プログラム呼び出し階層図

```
crashinfo.sh [メインスクリプト]
    |
    +-- usage() [行33]
    +-- cleanup() [行41] (trapハンドラ)
    +-- gdb_command() [行50] (GDB単一コマンド実行)
    +-- find_kernel() [行59] (カーネルバージョンマッチング)
    |
    +-- kgdb [行223] (バックトレース)
    |
    +-- ps -M -N [行232]
    +-- vmstat -M -N -s/-m/-z/-i [行237-256]
    +-- pstat -M -N -T/-s [行261-268]
    +-- iostat -M -N [行274]
    +-- ipcs -C -N -a/-T [行280-286]
    +-- netstat -M -N -s/-m/-anA/-aL [行299-320]
    +-- fstat -M -N [行325]
    +-- dmesg -a -M -N [行331]
    +-- config -x [行337]
    +-- ddb capture -M -N print [行344]
```

### データフロー図

```
[入力]                        [処理]                         [出力]

vmcore.{N} ──────────> kgdb [バックトレース] ──────> core.txt.{N}
info.{N} ────────────> sed [パニック文字列抽出]      (テキストファイル)
kernel ──────────────> gdb_command [シンボル読取]
bounds ──────────────> シェル演算 [ダンプ番号]
                       ps/vmstat/pstat/... [-M -N]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| crashinfo.sh | `usr.sbin/crashinfo/crashinfo.sh` | スクリプト | メインスクリプト（全処理を含む） |
| Makefile | `usr.sbin/crashinfo/Makefile` | ビルド | インストール設定 |
