コアダンプ

コアダンプ（英語：core dump）は、ある時点の使用中のメモリの内容をそのまま記録したものであり、一般に異常終了したプログラムのデバッグに使われる。最近では、特定のプロセスのメモリイメージ（あるいはその一部）とレジスタの内容などの情報を格納したファイルを指すのが一般的である。しかし、本来は使用中メモリの内容を全てプリントアウトしたものを指した。

その名前は、かつて主記憶用に利用された磁気コアメモリの内容を、ダンプトラックが砂利や小麦などを大量にダンプ（どさっと落とす）するかのようにプリントアウトすることから来ている。

異常終了したプロセスがコアダンプを出力することを、俗に「コアを吐く」という。

背景 
オペレーティングシステム (OS) が生まれ、大きなデータファイルを扱えるようになる以前は、コアダンプはメモリの内容を紙にプリントアウトしたものであり、一般に8進数か16進数（ヘックスダンプと呼ばれる）で記され、場合によっては、その横に何らかの形式に翻訳したものも表示された（機械語命令として翻訳したり、ASCII文字列として翻訳したり、十進数や浮動小数点数として翻訳したりする）。その後、コアダンプは特定のプロセスのアドレス空間の一部または全部のメモリイメージを格納したファイルとなり、同時にレジスタの値などの情報も格納するようになった。このようなファイルは適当なツールを使えば、かつての紙のコアダンプと同じように、人間が読める形式で参照可能となる。

コアダンプの原因 
コアダンプは、プログラマがプログラムのバグを特定するのに使われることが多い。高級言語では、コンパイラによって機械語命令列が生成される。コンパイル時にエラーとならない場合でも、実行してみると不正なメモリアクセスなどのエラーが発生することが多く、コアダンプが生成される。その原因は、データ量を小さく見積もったことに起因するバッファオーバフロー、初期化していない変数を使用したことによるNullポインタアクセスなどである。また、kill -3やgcoreでコアダンプを手動で生成することもできる。プロセスを終了する前に、gcoreコマンドの引数に  process-id を指定することで、process-id のコアダンプを取得できる。

コアダンプの利用 
コアダンプはある種の状況では有益なデバッグツールとなる。初期のスタンドアロンシステムやバッチ処理システムでは、コアダンプを使うことでユーザーは非常に高価なコンピュータ資源を独占せずにプログラムをデバッグすることができた。さらに、スイッチとライトを使ってデバッグするよりも、プリントアウトは便利であった。タイムシェアリングやバッチ処理やサーバ機能を兼ねているようなシステムでは、コアダンプを使うとOSのオフラインでのデバッグが可能となり、システムは即座に通常の作業に戻すことができた。コアダンプは後で解析したり、他のコアダンプと比較検討したりすることができた。コンピュータ自体にデバッグ機能を組み込むのは現実的ではないような組み込みシステムでも、コアダンプを用いれば他のコンピュータ上でシステムを分析することができる。いくつかのオペレーティングシステム（初期のUNIXなど）は、動作中のプロセスをデバッグする機能をサポートしていなかったため、コアダンプを使って障害発生時のプロセスのメモリ内容上でデバッグを行った。もちろん、現在でも対話型デバッガのないシステムでは有用である。また、障害の発生条件が不明で再現性がない場合もコアダンプの解析が重要となるし、タイミング条件で発生するバグの場合には、対話型デバッガを使っていると再現しないこともある。

多くのオペレーティングシステムでプログラムの中の致命的エラーは自動的にコアダンプを引き起こす。コアダンプで生成されるファイルの最大サイズは、limit coredumpsize max-sizeにて設定できる。また、コアダンプを全部削除するにはlimit coredumpsize 0が使用できる。従って、実際にコアダンプファイルが生成されたかどうかに関わらず、致命的エラーが発生したことを「コアを吐いた」と呼ぶこともある。プログラムのデバッグをするプログラマは、コアダンプが生成されるようになるunlimit coredumpsizeコマンドを知っている。

コアダンプはあるメモリ領域の内容をそのまま完全に格納している。従って、アセンブリ言語やメモリの使用法に制限のないC言語などで起きやすいポインターの不正（ポインターが壊れる現象）の状態を確認するのに適している。このようなバグに関しては、ソースレベルのデバッガは有効な情報を提供できないことが多い。デバッガは可能ならばシンボルテーブルを使ってダンプを翻訳し、変数名をシンボルとして表示したり、対応するソースコードを表示したりできる。またdump analyzerと呼ばれる特殊なツールも存在する。

最近のUnix系OSでは、コアダンプファイルをGNU BinutilsのBFDライブラリを使って読むことができ、GNUデバッガ (gdb) やobjdumpはこのライブラリを使っている。このライブラリはメモリアドレスを指定すると、そのアドレスに相当する位置のコアダンプ内の生のデータを返すだけで、変数やデータ構造に関する知識は持たない。従って、このライブラリを利用する側が変数のアドレスやデータ構造を把握する必要があり、対象プログラムのシンボルテーブルなどを使ってデバッグすることになる。

コアダンプをある時点で（gcoreコマンドなどで）セーブしておき、後でその状態に戻すのに使うこともできる。高可用性システムによっては、このようなコアダンプファイルをプロセッサ間で転送することで高可用性を実現することもある。この手法はGNU EmacsやPerlといった、起動時のコストが非常に高いソフトウエアでも利用されている。またプリコンパイルヘッダーと呼ばれる技術ではコンパイラがヘッダファイルを処理した時点でコアダンプを作成し、ヘッダファイル処理時間を節約するといった利用方法もある。

コアダンプファイルの形式 
古いOSでは、プロセスのアドレス空間は連続であり、コアダンプファイルは単にアドレス順にバイトが並んでいるだけだった。最近のOSでは、プロセスのアドレス空間には使っていない部分があり、それを表現するためにファイル形式も複雑化している。また、ダンプ採取時のプログラムの状態などの情報も格納される。

Unix系システムでは、コアダンプは一般に実行ファイルのファイルフォーマットを使っている。古いUNIXでは、a.outフォーマットが使われていた。Linux、System V、Solaris、BSDなどでは、ELF形式が使われている。macOSではMach-O 形式が使われている。

関連項目 
バグ
デバッガ
本物のプログラマはPascalを使わない - むしろFORTRANとコアダンプを用いるという冗談
例外処理
コールスタック
クラッシュダンプ

出典

参考文献

外部リンク 
GDBマニュアル
OS毎のファイル形式
Solaris
HP-UX
AIX
NetBSD
FreeBSD
OpenBSD
macOS

デバッグ