ダンプファイルの取り方

WER (Windows Error Reporting) を利用する

事前の設定がないとアプリクラッシュ時にダンプファイルを取得できない。

以下のレジストリを設定する必要がある。
32/64-bit プロセス両方のクラッシュに有効となる

\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps

LocalDumps キーは存在しないので新たに作成する。

名前 データの意味
DumpCount フォルダー内のダンプ ファイルの最大数。 最大値を超えると、フォルダー内の最も古いダンプファイルが新しいダンプファイルに置き換えられる。
DumpFolder ダンプ ファイルを格納するパス
DumpType 1: ミニ ダンプ、2: 完全ダンプ


詳細は下記リンクを参照。

タスクマネージャーを利用する

注意: 64-bit OS 上で 32-bit プロセスのダンプを取る場合、32-bit のタスクマネージャーからダンプを取らないと適切なダンプが取得できない。

64-bit のタスクマネージャーから 32-bit プロセスのダンプを取ると 64-bit のダンプが作成される。スタックに wow64cpu というのが表示されていたら、適切な "bit" でダンプが取れていない。

2022-11-14-1827.png

32-bit のタスクマネージャーは以下から起動できる。

C:\Windows\SysWOW64\Taskmgr.exe

Capturing memory dumps for 32-bit processes on an x64 machine

procdump を利用する

Sysinternals Toolsprocdump を利用してダンプを取ります。Microsoft Store からもインストールできますが、下記に記載した通り注意点があります。

もっとも単純なダンプの取り方は以下です。-ma オプションを付けるとフルダンプを取れます。

procdump -ma <PID>|<Process Name> [dumpfile]

Microsoft Store からインストールした場合の注意事項

Microsoft Store からインストールした procdump を使う場合、64-bit OS 上で 32-bit プロセスの 32-bit ダンプを取ることができません。
Sysinternals のサイトからダウンロードした procdump には、32/64-bit 両方の procdump が含まれています。32/64-bit どちらのプロセスをダンプする場合でも、常に procdump.exe を使っていれば、内部で適切に procdump.exe と procdump64.exe を使い分けてくれます。
以下の図は、64-bit プロセスのダンプを取る際に、procdump.exe の子プロセスとして procdump64.exe が起動され、64-bit ダンプが適切に取られる様子です。

2022-11-19-2131.png

そのため、Sysinternals のサイトから procdump をダウンロードした場合は、対象プロセスの bitness を気にすることなく、常に 32-bit の procdump.exe を使ってダンプを取れば適切なダンプを作成してくれます。

一方で、Microsoft Store からインストールした場合、OS の bitness に一致するパッケージしかインストールされません。 64-bit OS の場合 x64 パッケージしかインストールされません。そのため、32-bit プロセスをダンプする際、32-bit ダンプを作成することができないので注意が必要です。

ダンプの種類

  • ミニダンプ : -ma, -mp を指定しない場合に取得される。プロセスとプロセスのすべてのスレッドに関する基本的な情報だけが含まれる。イメージやマップドファイル、ヒープ、共有メモリ、プライベートデータのあるメモリ領域は含まれない。通常、取得するのに 1秒もかからない。
  • フルダンプ : -ma (memory all) を指定する。対象プロセスのコミット済みメモリ内容のすべてが含まれる。プロセスの仮想メモリ空間の全体を物理メモリにページインして、その後ダンプファイルに書き込むので、非常に時間がかかる。Ctrl+C でダンプを途中で終了できる。
  • ミニプラス : -mp を指定する。ProcDump 固有の種類。フルダンプと同等だが、ヒューリスティックアルゴリズムでダンプに含める情報を判断してサイズを小さくしてくれる。.NETアプリケーションへの使用は推奨されない。

様々な条件を指定してダンプを取る

ハンドルされない例外でクラッシュした時にダンプを取る

procdump -ma -e <PID>
  • -e 1 と指定すると、ファーストチャンス例外の発生時にもダンプを取れる
  • -e 1 -f "" と指定すると、ダンプは取得せずに、ファーストチャンス例外の情報を表示する。その後、セカンドチャンス例外が発生した場合はダンプが取得される。
  • -e 1 -f <filter>[,...] : <filter> には、例外コード、名前、メッセージと照合でき、大文字小文字は区別されず、ワイルドカード (*) をサポートする。<filter> に指定した検索文字列がファーストチャンス例外の出力に含まれるときにのみ、ダンプが取得される

ハング状態になったらダンプを取る

procdump -ma -h -w <Process Name>
  • -h : プロセスのトップレベルウィンドウが少なくとも 5秒間ウィンドウメッセージに応答せずハング状態になった時にダンプを取る
  • -w : 監視対象のプロセスが実行中でない場合、プロセスが起動するのを待つ

指定の回数・間隔でダンプを取る

procdump -ma -n <count> -s <sec> <PID>|<Process Name>
  • -n : 監視を終了するまでに作成するダンプの数。1つ目のダンプは開始直後に作成される
  • -s : 前のダンプの作成から次のダンプの作成を開始するまでの間隔を秒数で指定する。このオプションを指定しなかった場合の規定値は 10秒

CPU使用率を監視してダンプを取る

procdump -ma -c <CPU %> -s <sec> -n <count> <PID>|<Process Name>
  • -c : ダンプを取得する CPU使用率 (0-100) の上限閾値を指定する
  • -cl : ダンプを取得する CPU使用率 (0-100) の下限閾値を指定する
  • -u : 最大の CPU使用率が 100% から CPU数 x 100% に変わる。例えば、2コアシステムにおいて、-c 90 -u と指定した場合、プロセスの CPU使用率が 10秒間 45% を超えたときにダンプが作成される

以下の例は、Testapp プロセスの CPU 使用率が 3秒間連続して 80% を超えるたびにダンプファイルを作成し、計 3つのダンプを作成した時点で監視を終了する。

procdump -ma -c 80 -s 3 -n 3 testapp

コミットチャージを監視してダンプを取る

procdump -ma -m <commit-size MB> -n <count> -s <sec> <PID>|<Process Name>
  • m : ダンプを取得するメモリコミットチャージの上限閾値を MB で指定する。1秒間に1回チェックされる
  • ml : ダンプを取得するメモリコミットチャージの下限閾値を MB で指定する。1秒間に1回チェックされる

以下の例は、Testapp プロセスのコミットチャージが 200MB を超過したときにダンプを取得し、コミットチャージが 200MB を下回るまで、または 10個のダンプを取得するまで、5秒ごとにダンプを取得する

procdump -ma -m 200 -n 10 -s 5 testapp

任意のパフォーマンスカウンタを監視してダンプを取る

procdump -ma -p "<counter>" <upper-limit> -s <sec> -n <count> <PID>|<Process Name>
  • -p : ダンプの取得条件として、パフォーマンスカウンターとカウンターの上限閾値を指定する。1秒間に1回チェックされる
  • -pl : ダンプの取得条件として、パフォーマンスカウンターとカウンターの下限閾値を指定する。1秒間に1回チェックされる
  • カウンター名を取得するには、perfmon にそのカウンターを追加し、[パフォーマンスモニタのプロパティ] 画面の [データ] タブを参照する

以下の例は、システム上のプロセス数が 750 を超えたときに Taskmgr.exe プロセスのダンプを取得し、プロセス数が 750 以上の状態が続く場合はさらに 2つのダンプ(合計3つのダンプ)を 1秒ごとに取得する

procdump -ma -p "\System\Processes" 750 -s 1 -n 3 taskmgr.exe

予期しないプロセスの強制終了 (例外ではない) を監視する

procdump -ma -t <PID>|<Process Name>
  • -t : プロセスの終了時にダンプを取得する。ハンドルされていない例外によって引き起こされたのではない、予期しないプロセスの強制終了の原因を特定するのに便利

カーネルメモリダンプ

Sysinternals の LiveKd を利用してカーネルメモリダンプを取得できる。

livekd -k "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -ml -o <dumpfile>

参考