WinDbg で Dump ファイルを開く

Last Update: feedback 共有

こんにちは、Japan Developer Support Core チーム 平田 a.k.a ぴろとです。本日は WinDbg を使用して、ダンプ ファイルを開いて、解析を進める方法をご紹介します。今回は、クラッシュダンプの解析を進めていきます。まずはダンプといっても、取得をする目的を明確にする必要があります。以下に Dump ファイルについて説明を記載しましたため、合わせてご確認ください。

初めてインストールする方は以下のダウンロードページからダウンロードしてください
Windows 用デバッグ ツールのダウンロード

Dump ファイルについて (*.dmp)

こちらのファイルは、アプリケーションがクラッシュをしたり、ハングをした際にアプリケーションプロセスのメモリの内容をディスクへ書き出しを行うことで生成されるファイルとなります。  

ハング ダンプ

ハング ダンプは、プロセスがハングしてしまった場合に採取を検討します。アプリケーション クラッシュとは異なり、アプリケーション自体は何か例外を起こした訳ではないため、解析をする観点としては、何を待っているのか、無限ループになっているか等に注目をして解析を進めます。

クラッシュ ダンプ

こちらは、アプリケーションがクラッシュをした場合に取得するダンプとなります。これは、例外コードの確認、例外がどのような流れで発生したのかを注目し、解析を進めていくこととなります。

クラッシュ ダンプの採取

メモリリークや、クラッシュ等のパターンがいくつか試せるサンプル プログラムと WinDbg の理解を進めることができるドキュメントが提供されている素敵なサイトがあります。本当に素晴らしいドキュメントなので、是非ご参照ください。こちらから、CrashMe アプリケーションをダウンロードします。すでにビルドされていて、デバッグ シンボル ファイルもそろっているので、すぐに始められます。

windbg.info
WinDbg. From A to Z! 日本語版
リンク先のウェブサイトは、Microsoft のウェブサイトではなく、Microsoft とは異なりますことをご了承ください

こちら Release に格納されているリリース ビルド版のアプリケーションを起動し、[Dump Me] を押下してみます。今回は、\CrashMeDumps\v1.0-20201117-180813-31880-31888.dmp というダンプ ファイルが出力されました。こちらは、アプリケーション側でダンプをとってくれるように実装してあるので、簡単ですね。実際のダンプ採取を行う手順等についてダンプの採取方法として、今後の回で改めてご案内します。

ダンプを WinDbg にて開く

前回の EXE/DLL を開く場合と同様に Open dump file を選択し、ダイアログから上記のオペレーションにて出力された dmp ファイルを選択も忘れずに。
次に、デバッグ シンボル ファイルを参照するように設定します。まずは、Microsoft の提供するパブリック シンボルをダウンロードさせる設定をします。

.sympath srv*https://msdl.microsoft.com/download/symbols

その後、実際のアプリケーションのパスを入れます。リリース ビルドのフォルダーに CrashMe.pdb があるので、そのディレクトリになります。

.sympath+ C:\Users\test\Downloads\CrashMe\release

シンボル ファイルの設定が完了しましたら、!analyze -v コマンドを実行します。

!analyze -v

こちらのコマンドの結果を見てみましょう。

0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************


KEY_VALUES_STRING: 1

    Key  : AV.Dereference
    Value: NullPtr

    Key  : AV.Fault
    Value: Write

    Key  : Analysis.CPU.mSec
    Value: 811

    Key  : Analysis.DebugAnalysisProvider.CPP
    Value: Create: 8007007e on PIROTONE3950

    Key  : Analysis.DebugData
    Value: CreateObject

    Key  : Analysis.DebugModel
    Value: CreateObject

    Key  : Analysis.Elapsed.mSec
    Value: 1255

    Key  : Analysis.Memory.CommitPeak.Mb
    Value: 82

    Key  : Analysis.System
    Value: CreateObject

    Key  : Timeline.OS.Boot.DeltaSec
    Value: 247278

    Key  : Timeline.Process.Start.DeltaSec
    Value: 2

    Key  : WER.OS.Branch
    Value: vb_release

    Key  : WER.OS.Timestamp
    Value: 2019-12-06T14:06:00Z

    Key  : WER.OS.Version
    Value: 10.0.19041.1

    Key  : WER.Process.Version
    Value: 1.0.0.1


ADDITIONAL_XML: 1

OS_BUILD_LAYERS: 1

NTGLOBALFLAG:  0

PROCESS_BAM_CURRENT_THROTTLED: 0

PROCESS_BAM_PREVIOUS_THROTTLED: 0

APPLICATION_VERIFIER_FLAGS:  0

CONTEXT:  (.ecxr)
eax=00000000 ebx=00000001 ecx=0019fdfc edx=00000000 esi=0046bc18 edi=0019fdfc
eip=0045c137 esp=0019f6c4 ebp=0019f6f4 iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010282
CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+0x47:
0045c137 c70000000000    mov     dword ptr [eax],0    ds:002b:00000000=????????
Resetting default scope

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 0045c137 (CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+0x00000047)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 00000000
Attempt to write to address 00000000

PROCESS_NAME:  CrashMe.exe

WRITE_ADDRESS:  00000000 

ERROR_CODE: (NTSTATUS) 0xc0000005 - 0x%p          0x%p            Q           B         %s                              B

EXCEPTION_CODE_STR:  c0000005

EXCEPTION_PARAMETER1:  00000001

EXCEPTION_PARAMETER2:  00000000

FAULTING_LOCAL_VARIABLE_NAME:  pBadPtr

STACK_TEXT:  
0019f6f4 0040adce     0046bc18 00000111 0019f734 CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+0x47
0019f704 0040afdb     0019fdfc 00000083 00000000 CrashMe!_AfxDispatchCmdMsg+0x43
0019f734 004087df     00000083 00000000 00000000 CrashMe!CCmdTarget::OnCmdMsg+0x118
0019f758 0040655f     00000083 00000000 00000000 CrashMe!CDialog::OnCmdMsg+0x1b
0019f7a8 0040728e     00000000 0004058a f6d70f6c CrashMe!CWnd::OnCommand+0x90
0019f844 004025d1     00000111 00000083 0004058a CrashMe!CWnd::OnWndMsg+0x36
0019f864 0040559f     00000111 00000083 0004058a CrashMe!CWnd::WindowProc+0x22
0019f8cc 0040562c     00000000 00030920 00000111 CrashMe!AfxCallWndProc+0x9a
0019f8ec 76feef6b     00030920 00000111 00000083 CrashMe!AfxWndProc+0x34
0019f918 76fe5efa     004055f8 00030920 00000111 user32!_InternalCallWinProc+0x2b
0019f9fc 76fe52d9     004055f8 00000000 00000111 user32!UserCallWinProcCheckWow+0x33a
0019fa60 76fe390f     00eee1f0 00000000 0004058a user32!SendMessageWorker+0x829
0019fa80 6c786da8     00030920 00000111 00000083 user32!SendMessageW+0x6f
0019faa0 6c786d6d     00617b78 00000202 00000000 comctl32!Button_NotifyParent+0x39
0019fab8 6c7c69d3     00000202 0004058a 6c7c5fd0 comctl32!Button_ReleaseCapture+0x9a
0019fb54 76feef6b     0004058a 00000202 00000000 comctl32!Button_WndProc+0xa03
0019fb80 76fe5efa     6c7c5fd0 0004058a 00000202 user32!_InternalCallWinProc+0x2b
0019fc64 76fe3c5a     6c7c5fd0 00000000 00000202 user32!UserCallWinProcCheckWow+0x33a
0019fcd8 76fe7e68     005f96a0 0019fdfc 00000000 user32!DispatchMessageWorker+0x22a
0019fd0c 0040a0f9     00030920 005f96a0 0019fdfc user32!IsDialogMessageW+0x108
0019fd1c 00402b74     005f96a0 004087bf 005f96a0 CrashMe!CWnd::IsDialogMessageW+0x2e
0019fd24 004087bf     005f96a0 005f96a0 00030920 CrashMe!CWnd::PreTranslateInput+0x29
0019fd34 0040511b     005f96a0 005f96a0 0019fdfc CrashMe!CDialog::PreTranslateMessage+0x96
0019fd44 0040d103     00030920 005f96a0 005f96a0 CrashMe!CWnd::WalkPreTranslateTree+0x1f
0019fd58 0040d2c5     005f96a0 0040d149 005f96a0 CrashMe!AfxInternalPreTranslateMessage+0x3b
0019fd60 0040d149     005f96a0 0040d312 005f96a0 CrashMe!CWinThread::PreTranslateMessage+0x9
0019fd68 0040d312     005f96a0 00000000 0019fdfc CrashMe!AfxPreTranslateMessage+0x15
0019fd78 004046db     00000004 0019fdfc 0019fde8 CrashMe!AfxInternalPumpMessage+0x2b
0019fd9c 00408e85     00000004 f6d70ac0 0047d7b8 CrashMe!CWnd::RunModalLoop+0xca
0019fde8 0045b22f     f6d709e0 0047d7b8 00000000 CrashMe!CDialog::DoModal+0x12c
0019fec8 0045b110     000023f0 00000002 00000001 CrashMe!CCrashMeApp::InitInstance+0x8f
0019fed8 0042ff26     00400000 00000000 005f1f80 CrashMe!AfxWinMain+0x47
0019ff70 76bbfa29     002c3000 76bbfa10 0019ffdc CrashMe!__tmainCRTStartup+0x176
0019ff80 773f75f4     002c3000 9fb796fc 00000000 kernel32!BaseThreadInitThunk+0x19
0019ffdc 773f75c4     ffffffff 77417360 00000000 ntdll!__RtlUserThreadStart+0x2f
0019ffec 00000000     0042ff8f 002c3000 00000000 ntdll!_RtlUserThreadStart+0x1b


FAULTING_SOURCE_LINE:  c:\crashme\crashme\crashmedlg.cpp

FAULTING_SOURCE_FILE:  c:\crashme\crashme\crashmedlg.cpp

FAULTING_SOURCE_LINE_NUMBER:  766

FAULTING_SOURCE_CODE:  
No source found for 'c:\crashme\crashme\crashmedlg.cpp'


SYMBOL_NAME:  CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+47

MODULE_NAME: CrashMe

IMAGE_NAME:  CrashMe.exe

STACK_COMMAND:  ~0s ; .ecxr ; kb

FAILURE_BUCKET_ID:  NULL_POINTER_WRITE_c0000005_CrashMe.exe!CCrashMeDlg::OnBnClicked_DumpMeOnException

OS_VERSION:  10.0.19041.1

BUILDLAB_STR:  vb_release

OSPLATFORM_TYPE:  x86

OSNAME:  Windows 10

IMAGE_VERSION:  1.0.0.1

FAILURE_ID_HASH:  {3dc2efab-8a71-eb68-832d-9f05cebd3392}

Followup:     MachineOwner
---------

この内容から、重要な部分を抜粋します。ExceptionCode が c0000005 となっていますね。こちらのコードは、Access Violation の例外コードになります。

EXCEPTION_RECORD:  (.exr -1)
ExceptionAddress: 0045c137 (CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+0x00000047)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 00000000
Attempt to write to address 00000000

実際に例外が起きた箇所を確認するために重要な部分を抜粋します。

CONTEXT:  (.ecxr)
eax=00000000 ebx=00000001 ecx=0019fdfc edx=00000000 esi=0046bc18 edi=0019fdfc
eip=0045c137 esp=0019f6c4 ebp=0019f6f4 iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010282
CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+0x47:
0045c137 c70000000000    mov     dword ptr [eax],0    ds:002b:00000000=????????
Resetting default scope

こちらは、CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+0x47 に展開されている mov 命令語で eax に格納されている 0 をポインタとして参照をしていることがわかります。0 番アドレスは、参照ができないため、???????? になっていますね。
実際のソースコードの場所を確認するために、ソース コードもデバッガーに読み込ませましょう。

.srcpath+ C:\Users\test\Downloads\CrashMe

ソース コードを設定したら、.ecxr コマンドを実行します。(!analyze -v にて、例外が発生したコンテキスト レコードを表示するための例が載っています)

0:000> .ecxr
eax=00000000 ebx=00000001 ecx=0019fdfc edx=00000000 esi=0046bc18 edi=0019fdfc
eip=0045c137 esp=0019f6c4 ebp=0019f6f4 iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010282
CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+0x47:
0045c137 c70000000000    mov     dword ptr [eax],0    ds:002b:00000000=????????

ソース コードが設定されていると、このコマンドでソース コードとのマッチングがされるかと思います。デバッグ シンボルのなせる業です。ソース コードをデバッグ ログに残しておく場合には、lsa コマンドが利用できます。

0:000> lsa .
   762:     __try
   763:     {
   764:         // -> the clean way would be to 
   765:         int *pBadPtr = NULL;
>  766:         *pBadPtr = 0;
   767:     }
   768:     __except( GenerateDump(GetExceptionInformation(), MiniDumpWithFullMemory) )
   769:     {
   770:     }
   771: }

最後にスタックを確認します。crashmedlg.cpp の 766 行目であることがわかります。MFC のランタイムは、ソース コードが Visual Studio をインストールされると参照が可能です。そのため、デバッグ シンボルにてソース コードが解決されています。しかしながら、OS コンポーネントになる user32.dll 等は、解決できません。

0:000> k
*** Stack trace for last set context - .thread/.cxr resets it
# ChildEBP RetAddr      
00 0019f6f4 0040adce     CrashMe!CCrashMeDlg::OnBnClicked_DumpMeOnException+0x47 [c:\crashme\crashme\crashmedlg.cpp @ 766] 
01 0019f704 0040afdb     CrashMe!_AfxDispatchCmdMsg+0x43 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\cmdtarg.cpp @ 82] 
02 0019f734 004087df     CrashMe!CCmdTarget::OnCmdMsg+0x118 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\cmdtarg.cpp @ 381] 
03 0019f758 0040655f     CrashMe!CDialog::OnCmdMsg+0x1b [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dlgcore.cpp @ 85] 
04 0019f7a8 0040728e     CrashMe!CWnd::OnCommand+0x90 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp @ 2299] 
05 0019f844 004025d1     CrashMe!CWnd::OnWndMsg+0x36 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp @ 1755] 
06 0019f864 0040559f     CrashMe!CWnd::WindowProc+0x22 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp @ 1741] 
07 0019f8cc 0040562c     CrashMe!AfxCallWndProc+0x9a [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp @ 243] 
08 0019f8ec 76feef6b     CrashMe!AfxWndProc+0x34 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp @ 388] 
09 0019f918 76fe5efa     user32!_InternalCallWinProc+0x2b
0a 0019f9fc 76fe52d9     user32!UserCallWinProcCheckWow+0x33a
0b 0019fa60 76fe390f     user32!SendMessageWorker+0x829
0c 0019fa80 6c786da8     user32!SendMessageW+0x6f
0d 0019faa0 6c786d6d     comctl32!Button_NotifyParent+0x39
0e 0019fab8 6c7c69d3     comctl32!Button_ReleaseCapture+0x9a
0f 0019fb54 76feef6b     comctl32!Button_WndProc+0xa03
10 0019fb80 76fe5efa     user32!_InternalCallWinProc+0x2b
11 0019fc64 76fe3c5a     user32!UserCallWinProcCheckWow+0x33a
12 0019fcd8 76fe7e68     user32!DispatchMessageWorker+0x22a
13 0019fd0c 0040a0f9     user32!IsDialogMessageW+0x108
14 0019fd1c 00402b74     CrashMe!CWnd::IsDialogMessageW+0x2e [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winocc.cpp @ 197] 
15 0019fd24 004087bf     CrashMe!CWnd::PreTranslateInput+0x29 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp @ 4267] 
16 0019fd34 0040511b     CrashMe!CDialog::PreTranslateMessage+0x96 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dlgcore.cpp @ 79] 
17 0019fd44 0040d103     CrashMe!CWnd::WalkPreTranslateTree+0x1f [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp @ 2882] 
18 0019fd58 0040d2c5     CrashMe!AfxInternalPreTranslateMessage+0x3b [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp @ 233] 
19 0019fd60 0040d149     CrashMe!CWinThread::PreTranslateMessage+0x9 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp @ 773] 
1a 0019fd68 0040d312     CrashMe!AfxPreTranslateMessage+0x15 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp @ 255] 
1b 0019fd78 004046db     CrashMe!AfxInternalPumpMessage+0x2b [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\thrdcore.cpp @ 178] 
1c 0019fd9c 00408e85     CrashMe!CWnd::RunModalLoop+0xca [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\wincore.cpp @ 4322] 
1d 0019fde8 0045b22f     CrashMe!CDialog::DoModal+0x12c [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\dlgcore.cpp @ 587] 
1e 0019fec8 0045b110     CrashMe!CCrashMeApp::InitInstance+0x8f [c:\crashme\crashme\crashme.cpp @ 64] 
1f 0019fed8 0042ff26     CrashMe!AfxWinMain+0x47 [f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\winmain.cpp @ 37] 
20 0019ff70 76bbfa29     CrashMe!__tmainCRTStartup+0x176 [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 324] 
21 0019ff80 773f75f4     kernel32!BaseThreadInitThunk+0x19
22 0019ffdc 773f75c4     ntdll!__RtlUserThreadStart+0x2f
23 0019ffec 00000000     ntdll!_RtlUserThreadStart+0x1b

今回は以上になります。


本ブログの内容は弊社の公式見解として保証されるものではなく、開発・運用時の参考情報としてご活用いただくことを目的としています。もし公式な見解が必要な場合は、弊社ドキュメント (https://docs.microsoft.comhttps://support.microsoft.com) をご参照いただくか、もしくは私共サポートまでお問い合わせください。