CRASHPAD / OVERVIEW DESIGN

Crashpad の設計概要

クラッシュしたプロセスから
何を、どうやって記録するか。

日本語訳をもとにした設計ドキュメントのスライド版

翻訳元:86aed0d4 · 2026 年 10 月 28 日取得
原文の TODO・将来予定を含む、その時点の設計記述です。

01 / 目的

クラッシュの状態を、忠実に残す

  • クラッシュ後のレポートを取得・保存し、上流の収集サーバーへ送信する。
  • できる限り忠実かつ広範囲に、最小限の手間でプロセス状態を取得する。
  • 診断用に、必要に応じてクラッシュしていないプロセスのダンプも取得する。
  • プロセスごとのキーと値のペアでメタデータを付加。高度な用途には拡張ポイントを用意する。

02 / 背景

ユーザーの報告だけでは、再現できない

  • 大規模なソフトウェアにはバグがあり、互換性の問題もクラッシュを引き起こす。
  • OS のバージョン、サードパーティー製ソフトウェア、競合状態など、実行環境が異なる。
  • 問題に遭遇しても報告されないことが多く、報告に診断に必要な情報がそろうとも限らない。
  • クラッシュのテレメトリを自動収集し、報告の負担を減らしながらハードウェアとソフトウェアの状態を残す。

原文 TODO(siggi):この例を挙げる。

02 / 背景

解析と集計は、サーバーで行う

  • クライアントはクラッシュ後のダンプを取得して送信する。
  • 収集サーバーでスタック走査・シンボル解決・評価・集計を行う。
  • 大容量のアンワインド情報やデバッグシンボルをエンドユーザーへ配布せずに済み、解析のリソース負担も移せる。
  • 未解析のダンプを残すことで、個別の問題を詳細に調査できる。
  • 原因別の集計から、発生頻度や潜在的なセキュリティ影響を評価する。

02 / 背景

壊れたプロセスの中で、仕事をしすぎない

  • 全状態は保存・送信には大きすぎる。診断と修正に必要な一部を、ヒューリスティックに選ぶ。
  • クラッシュしたプロセスの状態は不確定。ヒープなどの大域的な状態が壊れている可能性もある。
  • クラッシュしたプロセス内での実行を、できるだけ少なくする。
  • このために使える OS の機能は、プラットフォームごとに異なる。

03 / 概要

クライアントとハンドラーを分ける

クライアント登録・メタデータ
→
ハンドラー取得・保存・送信
→
収集サーバー解析・集計
  • Crashpad はアプリケーションに組み込む、クライアント側のライブラリ。
  • 通常、ハンドラーは 1 つ以上のクライアントとは別のプロセスで動く。
  • iOS では OS の制約により、ハンドラー用の別プロセスは存在しない。

03 / ハンドラー

登録を受け付け、状態を保存する

  • 組み込み側が用意するプロセス内でハンドラーをインスタンス化する。
  • IPC でクライアント登録を受け付け、利用できる OS の支援機能でクラッシュ通知を受ける。
  • クラッシュ時にスナップショットを取得し、ダンプをデータベースへ保存。設定に応じて送信する。
  • 異なるビット数にも対応。ただし Windows の 32 ビットハンドラーは 32 ビットクライアントのみ。64 ビットハンドラーは 32 ビットプロセスのほぼすべての詳細を取得できる。

03 / クライアント

登録と、メタデータの伝達

  • 実行可能ファイルやロード可能なライブラリに、クライアントライブラリをリンクする。
  • IPC や OS 固有の支援機能を使ってハンドラーに登録する。
  • 各実行可能モジュールに CrashpadInfo 構造体が埋め込まれる。
  • クライアントは、クラッシュとともに残したい状態を CrashpadInfo に更新する。
  • 複数のモジュールが CrashpadInfo を持てるが、プロセスの登録は 1 回でよい。

03 / 構成図

組み込み側と Crashpad

組み込み側(水色)、複数のクライアントモジュール(濃い青)、Crashpad(緑)の概念的な関係
水色:組み込み側 / 濃い青:クライアントモジュール / 緑:Crashpad

04 / 詳細設計・要件

診断できる精度と、同意の尊重

  • マシン・OS・アプリケーションの状態を、原因の診断と修正に十分な詳細さと忠実さで取得する。
  • 各レポートにグローバルに一意な ID を割り当て、ユーザーの報告やバグ報告と関連づける。
  • ユーザーの同意なしにレポートをアップロードしない。
  • クライアントではないプロセスのレポートを取得・アップロードしない。

04 / 概念

識別子と、保存する情報

Client ID
データベースの単一インスタンスに紐づく UUID。特定のクラッシュの影響を受けるエンドユーザー数の把握に使う。
Crash ID / サーバー ID
個々のレポートの UUID。送信後はサーバー ID も付与され、両方をデータベースの索引に登録する。
Annotations
CrashpadInfo が指す {文字列, 文字列} の辞書。クラッシュ時のアプリケーション状態を伝える。
Database
永続的なクライアント設定と、アップロード待ちのクラッシュダンプを格納する。

04 / 概念

プロセスとインターフェース

クライアントプロセス
Crashpad ハンドラーに登録したプロセス。
ハンドラープロセス
ハンドラーライブラリを動かすプロセス。専用の実行可能ファイル、またはクライアントと同じ実行可能ファイルの特別な起動モードを使う。
CrashpadInfo
クライアントモジュールがハンドラーへ情報を提供する構造体。
収集サーバー
送信先。原文は内部向けの クラッシュサーバーのドキュメントを参照している。

原文 TODO(siggi):ほかにも概念を追加する?

04 / 全体像

OS 固有の実装を、共通の境界で包む

Crashpad のインターフェース、実装、クライアントアプリケーションの階層構造
濃い青:インターフェース / 水色:実装 / 灰色:組み込み側のアプリケーション。可能な限り OS に依存しないインターフェースを公開する。

05 / 登録

macOS と iOS

  • macOS:ハンドラーが監視する Mach ポートを、自身の EXC_CRASH 例外ポートに設定する。
  • ポートは新しいハンドラーの起動、または既存のシステムサービスから取得する。
  • 登録はカーネルが管理し、既定で子プロセスへ継承。プロセスツリーの最上位だけ登録すればよい。
  • 登録解除にも対応。古いクライアントが更新版を起動する場合などに使う。
  • iOS:SIGABRT のシグナルハンドラーと、利用可能な一部の例外の Mach 例外ハンドラーを登録する。

05 / 登録

Windows:通常と初回起動の 2 方式

  • いずれも、クライアント内の構造体のアドレスをハンドラーへ通知する。ExceptionInformation はクラッシュ用と非クラッシュ用の 2 つ。
  • 通常:名前付きパイプへ登録要求を書く。ハンドラーがイベントを作成・クライアントへ複製し、応答でハンドルを返す。この処理はブロックする。
  • ハンドラーの初回作成:起動をブロックしないよう、クライアントがイベントハンドルを作成し、新しいハンドラーへ継承させる。
  • 初回作成ではコマンドライン引数で、ハンドル値と ExceptionInformation の位置を通知する。

05 / 登録

Linux / Android:ソケットペア

  • クライアントとハンドラーをつなぐ、接続済みソケットペアが登録を表す。
  • 専用接続:クラッシュに応じた起動や、別クライアントのための起動で既定。Android の隔離プロセスをトレースする ptrace ブローカーに必要。
  • 共有接続:長時間稼働するハンドラーで既定。任意の数のクライアントで 1 組を共有できる。
  • 最初にハンドラーを起動するプロセスがソケットペアを作成し、継承などでクライアント側の端点を共有する。

06 / 例外の捕捉

macOS:カーネルが別プロセスへ通知

  • OS が、クライアントの例外ポートに設定された Mach ポートを通してハンドラーへ通知する。
  • 例外はカーネルが配送するため、クラッシュしたプロセス内でコードを実行する必要がない。
  • iOS:Mach 例外ポートまたはシグナルハンドラーで通知を受け、例外をプロセス内で処理する。
  • iOS のその場の出力は minidump ではなく、中間ダンプファイルとなる。

06 / 例外の捕捉

Windows:UEF からイベントで通知

  • OS は、クラッシュしたスレッドのコンテキストで例外を配送する。
  • クライアント内に UnhandledExceptionFilter(UEF)を登録する。
  • UEF まで例外が伝播すると、例外情報とクラッシュしたスレッド ID を登録済みの ExceptionInformation に格納する。
  • イベントハンドルをシグナル状態にし、ハンドラーへ例外処理の開始を知らせる。

06 / WINDOWS の注意点

レポートを生成できない場合がある

  • スタックが破壊されていると例外を配送できず、OS がプロセスを即座に終了する。
  • スレッド内で例外が処理されると UEF に届かない。システムライブラリの保護されたコールバック、ウィンドウメッセージ、DLL エントリーポイントなどで起こる。
  • システムやランタイムが、破損や不正な呼び出しを検出して即座に終了させる場合もある。
  • Windows Error Reporting(WER)にはプロセス外の例外処理を登録する仕組みがあるが、扱いが難しく、これらの制約の多くも解消しない。

原文の参照:Crashpad issue 133

06 / 例外の捕捉

Linux / Android:シグナルから通知

  • OS がクラッシュしたスレッドへシグナルを配送する。
  • シグナルハンドラーがソケットで、クラッシュの発生と例外情報の位置を通知する。
  • 共有接続:通信は完全に一方向。要求後は、ハンドラーからの SIGCONT またはタイムアウトまで待つ。
  • 専用接続:ハンドラーはソケットで応答できる。クラッシュしたプロセスから fork された ptrace ブローカーが対象への ptrace 要求を実行し、結果をハンドラーへ送る。

07 / CRASHPADINFO

各モジュールから、必要な情報を読む

  • ハンドラーは全モジュールを走査し、特別な名前付きセクションにある CrashpadInfo を探す。
  • 識別用のマジック値・サイズ・バージョンを持ち、古いクライアントと新しいハンドラーの後方互換性を確保する。
  • 新しいクライアントと古いハンドラーの前方互換性が必要になる可能性もあるが、原文時点では未発生。
  • メモリ取得量の上限、動作を制御する 3 値フラグ、アノテーション辞書へのポインターなどを含む。

08 / SNAPSHOT と MINIDUMP

取得する実体と、書き出す形式を分離

  • Snapshot:マシンや OS の構成要素を表すインターフェース層。具象実装はプロセスのメモリや minidump などをデータの実体にできる。
  • OS の内部に深く関わる取得処理は、OS ごとの具象クラスで実装する。多くは Snapshot を継承する。
  • Minidump:共通の Snapshot をシリアライズしてディスクへ書くため、実装自体は OS に依存しない。
  • レポートは Windows の minidump 形式。アノテーションなどの独自拡張を含む。

原文 TODO(siggi):2 段階の書き込みと内容の順序を説明する。

08 / ダンプの内容

全状態から、診断に必要な一部を選ぶ

  • ロードされたモジュール:実行可能ファイル・共有ライブラリ。
  • 実行中のスレッド一覧:各スレッドのレジスターとスタックメモリ。
  • コマンドラインや環境など、プロセスの OS 関連の状態の一部。
  • レジスターやスタックから参照されている可能性があるメモリの一部。
  • 具体的な内容は OS ごとに異なる。全状態ではなく、ヒューリスティックに選んだ一部をスナップショットにする。

08 / ダンプの作成手順

停止 → 取得 → 保存 → 停止解除

  1. クラッシュしたプロセスを一時停止する。
  2. ハンドラーのメモリにスナップショットを構築する。各モジュールの CrashpadInfo の内容で記録の詳細度を制御する。
  3. minidump ファイルへ書き出し、データベースに追加する。
  4. 書き込み後、対象プロセスの一時停止を解除する。
  5. クラッシュ時は OS またはハンドラーがプロセスを強制終了する。非クラッシュダンプの要求時は、この終了は行わない。

09 / データベース

設定とダンプを永続化する

  • 作成時に一意な Client ID を設定し、その後の全レポートに記録して上流へ伝える。アプリ独自のユーザー・インストール・マシン ID とは別の ID。
  • アップロード有効化ビットを保存する。ユーザー同意の取得・変更通知はクライアントアプリケーションが担う。
  • 保存するダンプ数と合計サイズの上限を設定できる。
  • 各ダンプにアップロード状態を保存し、成功時にはサーバー ID も残す。

09 / データベースの実装

共通の設定、OS ごとのプロパティ

共通
バイナリの settings.dat(crashpad::Settings::Data)と、ダンプを格納するディレクトリ。
macOS
minidump ファイルのファイルシステム拡張属性にプロパティを保存する。
iOS
同じく拡張属性に保存。さらにデータベースの隣に中間ダンプファイルを保存する。
Windows
データベースディレクトリの最上位にある metadata バイナリファイルへ保存する。

10 / アップロード・通信形式

Breakpad との互換性を保つ

  • HTTP(S) の MIME マルチパートメッセージを使う。
  • 全 CrashpadInfo のアノテーションを統合し、フォームデータの「クラッシュキー」にする。
  • minidump は upload_file_minidump という名前の application/octet-stream 添付ファイルにする。リクエストボディ全体を gzip 圧縮できる。
  • 製品・バージョン・Client ID などは通常 minidump に保存されるが、互換性のためフォームにも取り出して送る。
  • 原文では一時的な互換措置。将来のプロトコル変更で、アノテーションの重複送信・処理をなくす想定。

10 / アップロード・トランスポート

URL を指定し、HTTPS で送る

  • 組み込み側のクライアントが、ハンドラーに渡すコマンドラインで収集サーバーの URL を制御する。
  • ハンドラーは HTTP と HTTPS に対応する。
  • 中間者による盗聴からプライバシーを守るため、原文は HTTPS を強く推奨する。

原文 TODO(mmentovai):証明書ピンニング。

10 / アップロード制限と再試行

原文の戦略:1 時間に 1 回

  • 収集サーバーへの DDoS と、クライアントの過大な転送を避けるためアップロードを制限する。
  • 原文時点の戦略は 1 時間に 1 回。失敗したアップロードは打ち切り、再試行しない。
  • 制限を外した実験では、同じクライアントで短時間に起きる複数のクラッシュは、ほぼ同じ原因だった。制限で失う有用な情報は少ないが、総回数の復元は望ましい。
  • 再試行しないと、ネットワーク切断やサスペンド・レジューム時だけのクラッシュを観測できない。原文では変更予定。

現在の実装の説明ではありません。原文の将来予定:issue 23。

11 / 拡張性

クライアントと組み込み側の拡張

  • クライアント:CrashpadInfo で、レポートに含めるアドレス範囲や、ユーザー定義の minidump ストリームを指定する。クラッシュ前に更新しておく。
  • ハンドラーの組み込み側:main 関数へ「ユーザーストリームデータソース」のインスタンスを渡す。
  • データソースは minidump の書き込みごとに呼ばれ、独自のストリームを追加できる。
  • たとえば、クラッシュ時にメモリ不足などのリソース逼迫があったかを、システムやアプリケーションの状態から計算して記録する。

12 / 依存関係

Chromium の内側と外側

  • システムのヘッダーと API に加え、Chromium 外では base ライブラリのサブセット mini_chromium に依存する。
  • 外部クライアントが Chromium の base 全体へ直接依存せずに利用できる。
  • Chromium 内では、mini_chromium の代わりに Chromium 自身の base を使い、コードの重複と手間を抑える。
  • 欠点:利用する機能の範囲で、base のインターフェース・実装変更に mini_chromium を追従させる必要がある。

「注意事項」の原文 TODO(anyone):実施しなかったこと、単純な方法ではうまくいかない理由、ほかの注意点を記載する。

13 / セキュリティ

読み出すデータを、慎重に扱う

  • サンドボックス内のプロセスから状態を取得し、minidump をディスクへ書くため、セキュリティ境界をまたぐ可能性がある。
  • ハンドラーは専用アクセサーでポインターの有効性を検査し、指定範囲内へのアクセスを強制する。
  • クラッシュしたプロセスから読むすべてのデータを慎重に扱う。
  • ハンドラーへの情報の流れは完全に一方向。クライアントへ返すのは、処理完了を示す 1 ビットの通知のみ。

14 / プライバシー

メモリには、ユーザーの情報がある

  • ダンプにはユーザー ID、パスワード、クレジットカード情報、URL など、アプリケーションに預けられた任意の内容が入りうる。
  • クライアントはアップロードへの同意を取得・尊重し、データベースのアップロード状態を適切に管理する。
  • ハンドラーに登録していないプロセスのクラッシュは、決してアップロードしない。
  • 一部の OS では、登録が子プロセスへ継承される点にも注意する。

15 / 出典とライセンス

元の文書・図について

このスライドは Crashpad の設計概要(日本語訳)の内容を、発表用に再構成・要約したものです。詳細な文章は日本語訳を参照してください。

Crashpad Overview Design(固定コミット)
86aed0d4e037f9af6347b8b21daa37ea779234b2
日本語訳の翻訳元取得日:2026 年 10 月 28 日

本文・図:Copyright 2017 The Crashpad Authors
Apache License 2.0
変更:日本語訳をスライド用に再構成・要約し、操作 UI とスタイルを追加。

iOS の詳細:iOS Overview Design(制約・プロセス内ハンドラー・中間ダンプ)