次の方法で共有


WinDbg (ユーザー モード) を始める

WinDbg は、Windows 用デバッグ ツールに含まれているカーネル モードおよびユーザー モードデバッガーです。 次の実践的な演習は、WinDbg をユーザー モード デバッガーとして使い始めるのに役立ちます。

Windows 用デバッグ ツールを取得する方法については、「WinDbg Windows デバッガーをダウンロードしてインストールする」を参照してください。

デバッグ ツールをインストールしたら、64 ビット (x64) および 64 ビット ARM バージョンのツールのインストール ディレクトリを見つけます。 例えば:

  • C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
  • C:\Program Files (x86)\Windows Kits\10\Debuggers\arm64

メモ帳を開き、WinDbg をアタッチする

  1. インストール ディレクトリに移動し、WinDbg.exeを開きます。

  2. [ファイル] メニューから [実行可能プログラムの起動] を選択します。 [実行可能ファイルの起動] ダイアログで、notepad.exeを含むフォルダーに移動します。 (通常、notepad.exe ファイルは C:\Windows\System32 にあります)。ファイル名に「notepad.exe」と入力します。 を選択し、を開きます。

    メモ帳が開いている WinDbg のスクリーンショット。

  3. WinDbg ウィンドウの下部付近のコマンド ラインで、次のコマンドを入力します。

    .sympath srv*

    出力は次の例のようになります。

    Symbol search path is: srv*
    Expanded Symbol search path is: cache*;SRV
    

    シンボル検索パスは、シンボル (PDB) ファイルを検索する場所を WinDbg に指示します。 デバッガーには、関数名や変数名などのコード モジュールに関する情報を取得するためにシンボル ファイルが必要です。

    次に、次のコマンドを入力します。

    .reload

    .reload コマンドは、シンボル ファイルを検索して読み込む最初の検索を行うように WinDbg に指示します。

  4. notepad.exe モジュールのシンボルを表示するには、次のコマンドを入力します。

    x notepad!*

    手記

    出力が表示されない場合は、「.reload /f」と入力してシンボルの読み込みを強制します。 追加のシンボル読み込み情報を表示するには、!sym noisy を使用します。

    mainを含む notepad.exe モジュール内のシンボルを表示するには、を使用してシンボル 検査コマンドを使用して、マスクに一致するモジュールを一覧表示します。

    x notepad!wWin*

    出力は次の例のようになります。

    00007ff6`6e76b0a0 notepad!wWinMain (wWinMain)
    00007ff6`6e783db0 notepad!wWinMainCRTStartup (wWinMainCRTStartup)
    
  5. ブレークポイントを notepad!wWinMainに配置するには、次のコマンドを入力します。

    bu notepad!wWinMain

    ブレークポイントが設定されたことを確認するには、次のコマンドを入力します。

    bl

    出力は次の例のようになります。

    0 e Disable Clear  00007ff6`6e76b0a0     0001 (0001)  0:**** notepad!wWinMain
    
  6. メモ帳プロセスを開始するには、次のコマンドを入力します。

    g

    メモ帳は WinMain 関数まで実行されてから、デバッガーを中断します。

    Breakpoint 0 hit
    notepad!wWinMain:
    00007ff6`6e76b0a0 488bc4          mov     rax,rsp
    

    メモ帳プロセスに現在読み込まれているコード モジュールの一覧を表示するには、次のコマンドを入力します。

    lm

    出力は次の例のようになります。

    0:000> lm
    start             end                 module name
    00007ff6`6e760000 00007ff6`6e798000   notepad    (pdb symbols)          C:\ProgramData\Dbg\sym\notepad.pdb\BC04D9A431EDE299D4625AD6201C8A4A1\notepad.pdb
    00007ff8`066a0000 00007ff8`067ab000   gdi32full   (deferred)             
    00007ff8`067b0000 00007ff8`068b0000   ucrtbase   (deferred)             
    00007ff8`06a10000 00007ff8`06aad000   msvcp_win   (deferred)             
    00007ff8`06ab0000 00007ff8`06ad2000   win32u     (deferred)             
    00007ff8`06b40000 00007ff8`06e08000   KERNELBASE   (deferred)             
    00007ff8`07220000 00007ff8`072dd000   KERNEL32   (deferred)             
    00007ff8`07420000 00007ff8`07775000   combase    (deferred)             
    00007ff8`07820000 00007ff8`079c0000   USER32     (deferred)             
    00007ff8`079c0000 00007ff8`079f0000   IMM32      (deferred)             
    00007ff8`07c00000 00007ff8`07c2a000   GDI32      (deferred)             
    00007ff8`08480000 00007ff8`085ab000   RPCRT4     (deferred)             
    00007ff8`085b0000 00007ff8`0864e000   msvcrt     (deferred)             
    00007ff8`08c40000 00007ff8`08cee000   shcore     (deferred)             
    00007ff8`08db0000 00007ff8`08fa5000   ntdll      (pdb symbols)          C:\ProgramData\Dbg\sym\ntdll.pdb\53F12BFE149A2F50205C8D5D66290B481\ntdll.pdb
    00007fff`f8580000 00007fff`f881a000   COMCTL32   (deferred)    
    

    スタック トレースを表示するには、次のコマンドを入力します。

    k

    出力は次の例のようになります。

    0:000> k
    00 000000c8`2647f708 00007ff6`6e783d36     notepad!wWinMain
    01 000000c8`2647f710 00007ff8`07237034     notepad!__scrt_common_main_seh+0x106
    02 000000c8`2647f750 00007ff8`08e02651     KERNEL32!BaseThreadInitThunk+0x14
    03 000000c8`2647f780 00000000`00000000     ntdll!RtlUserThreadStart+0x21
    
  7. メモ帳の実行を再開するには、次のコマンドを入力します。

    g

  8. メモ帳を中断するには、[ファイル] メニューの [中断] を選択します。

  9. ZwWriteFileでブレークポイントを設定して確認するには、次のコマンドを入力します。

    bu ntdll!ZwWriteFile

    bl

  10. メモ帳の実行をもう一度開始するには、「g」と入力します。 メモ帳ウィンドウで、テキストを入力します。 [ファイル] メニューで、 [保存] を選択します。 実行中のコードは、ZwCreateFileでエラーが発生して中断します。 k コマンドを入力して、スタック トレースを確認します。

    WinDbg のスタック トレースのスクリーンショット。

    コマンド ラインの左側にある WinDbg ウィンドウに、プロセッサ番号とスレッド番号が表示されます。 この例では、現在のプロセッサ番号は 0、現在のスレッド番号は 11 (0:011>) です。 このウィンドウには、プロセッサ 0 で実行されているスレッド 11 のスタック トレースが表示されます。

  11. メモ帳プロセス内のすべてのスレッドの一覧を表示するには、次のコマンド (チルダ) を入力します。

    ~

    出力は次の例のようになります。

    0:011> ~
       0  Id: 5500.34d8 Suspend: 1 Teb: 000000c8`262c4000 Unfrozen
       1  Id: 5500.3960 Suspend: 1 Teb: 000000c8`262c6000 Unfrozen
        2  Id: 5500.5d68 Suspend: 1 Teb: 000000c8`262c8000 Unfrozen
        3  Id: 5500.4c90 Suspend: 1 Teb: 000000c8`262ca000 Unfrozen
        4  Id: 5500.4ac4 Suspend: 1 Teb: 000000c8`262cc000 Unfrozen
        5  Id: 5500.293c Suspend: 1 Teb: 000000c8`262ce000 Unfrozen
        6  Id: 5500.53a0 Suspend: 1 Teb: 000000c8`262d0000 Unfrozen
        7  Id: 5500.3ca4 Suspend: 1 Teb: 000000c8`262d4000 Unfrozen
        8  Id: 5500.808 Suspend: 1 Teb: 000000c8`262da000 Unfrozen
       10  Id: 5500.3940 Suspend: 1 Teb: 000000c8`262dc000 Unfrozen
     . 11  Id: 5500.28b0 Suspend: 1 Teb: 000000c8`262de000 Unfrozen
       12  Id: 5500.12bc Suspend: 1 Teb: 000000c8`262e0000 Unfrozen
       13  Id: 5500.4c34 Suspend: 1 Teb: 000000c8`262e2000 Unfrozen
    

    この例では、14 個のスレッドのインデックスは 0 から 13 です。

  12. スレッド 0 のスタック トレースを確認するには、次のコマンドを入力します。

    ~0s

    k

    出力は次の例のようになります。

    0:011> ~0s
    0:011> ~0s
    win32u!NtUserGetProp+0x14:
    00007ff8`06ab1204 c3              ret
    0:000> k
     # Child-SP          RetAddr               Call Site
    00 000000c8`2647bd08 00007ff8`07829fe1     win32u!NtUserGetProp+0x14
    01 000000c8`2647bd10 00007fff`f86099be     USER32!GetPropW+0xd1
    02 000000c8`2647bd40 00007ff8`07d12f4d     COMCTL32!DefSubclassProc+0x4e
    03 000000c8`2647bd90 00007fff`f8609aba     SHELL32!CAutoComplete::_EditWndProc+0xb1
    04 000000c8`2647bde0 00007fff`f86098b7     COMCTL32!CallNextSubclassProc+0x9a
    05 000000c8`2647be60 00007ff8`0782e858     COMCTL32!MasterSubclassProc+0xa7
    06 000000c8`2647bf00 00007ff8`0782de1b     USER32!UserCallWinProcCheckWow+0x2f8
    07 000000c8`2647c090 00007ff8`0782d68a     USER32!SendMessageWorker+0x70b
    08 000000c8`2647c130 00007ff8`07afa4db     USER32!SendMessageW+0xda
    
  13. デバッグを終了し、メモ帳プロセスからデタッチするには、次のコマンドを入力します。

    qd

独自のアプリケーションを開き、WinDbg をアタッチする

たとえば、この小さなコンソール アプリケーションを作成してビルドしたとします。

...
void MyFunction(long p1, long p2, long p3)
{
    long x = p1 + p2 + p3;
    long y = 0;
    y = x / p2;
}

void main ()
{
    long a = 2;
    long b = 0;
    MyFunction(a, b, 5);
}

この演習では、ビルドされたアプリケーション (MyApp.exe) とシンボル ファイル (MyApp.pdb) が C:\MyApp\x64\Debug にあると仮定します。 また、アプリケーションのソース コードが C:\MyApp\MyApp and that the target machine compiled MyApp.exe内にあることを前提としています。

  1. WinDbg を開きます。

  2. [ファイル] メニューの [実行可能ファイルの起動] を選択します。 [実行可能ファイルの起動] ダイアログで、C:\MyApp\x64\Debug に移動します。 ファイル名に「MyApp.exe」と入力します。 [Open (開く)] を選択します。

  3. 次のコマンドを入力します。

    .symfix

    .sympath+ C:\MyApp\x64\Debug

    このコマンドは、アプリケーションのシンボルとソース コードを検索する場所を WinDbg に指示します。 この場合、シンボルにはソース ファイルへの完全修飾パスがあるため、.srcpath 使用してソース コードの場所を設定する必要はありません。

  4. 次のコマンドを入力します。

    .reload

    bu MyApp!main

    g

    アプリケーションは、その main 関数に達するとデバッガを中断します。

    WinDbg には、ソース コードとコマンド ウィンドウが表示されます。

    WinDbg に表示されるソース コードのスクリーンショット。

  5. [デバッグ] メニューの [ステップ イン] を選択します (または F11 キーを押します)。 MyFunctionにステップインするまでステップを続けます。 y = x / p2行にステップ インすると、アプリケーションがクラッシュし、デバッガーに分割されます。

    出力は次の例のようになります。

    (1450.1424): Integer divide-by-zero - code c0000094 (first chance)
    First chance exceptions are reported before any exception handling.
    This exception may be expected and handled.
    MyApp!MyFunction+0x44:
    00007ff6`3be11064 f77c2428    idiv  eax,dword ptr [rsp+28h] ss:00000063`2036f808=00000000
    
  6. 次のコマンドを入力します。

    !analyze -v

    WinDbg では、問題の分析が表示されます (この場合、0 による除算)。

    FAULTING_IP:
    MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7]
    00007ff6`3be11064 f77c2428        idiv    eax,dword ptr [rsp+28h]
    
    EXCEPTION_RECORD:  ffffffffffffffff -- (.exr 0xffffffffffffffff)
    ExceptionAddress: 00007ff63be11064 (MyApp!MyFunction+0x0000000000000044)
       ExceptionCode: c0000094 (Integer divide-by-zero)
      ExceptionFlags: 00000000
    NumberParameters: 0
    ...
    STACK_TEXT:  
    00000063`2036f7e0 00007ff6`3be110b8 : ... : MyApp!MyFunction+0x44
    00000063`2036f800 00007ff6`3be1141d : ... : MyApp!main+0x38
    00000063`2036f840 00007ff6`3be1154e : ... : MyApp!__tmainCRTStartup+0x19d
    00000063`2036f8b0 00007ffc`b1cf16ad : ... : MyApp!mainCRTStartup+0xe
    00000063`2036f8e0 00007ffc`b1fc4629 : ... : KERNEL32!BaseThreadInitThunk+0xd
    00000063`2036f910 00000000`00000000 : ... : ntdll!RtlUserThreadStart+0x1d
    
    STACK_COMMAND: dt ntdll!LdrpLastDllInitializer BaseDllName ;dt ntdll!LdrpFailureData ;.cxr 0x0 ;kb
    
    FOLLOWUP_IP:
    MyApp!MyFunction+44 [c:\myapp\myapp\myapp.cpp @ 7]
    00007ff6`3be11064 f77c2428        idiv    eax,dword ptr [rsp+28h]
    
    FAULTING_SOURCE_LINE:  c:\myapp\myapp\myapp.cpp
    
    FAULTING_SOURCE_FILE:  c:\myapp\myapp\myapp.cpp
    
    FAULTING_SOURCE_LINE_NUMBER:  7
    
    FAULTING_SOURCE_CODE:  
         3: void MyFunction(long p1, long p2, long p3)
         4: {
         5:     long x = p1 + p2 + p3;
         6:     long y = 0;
    >    7:  y = x / p2;
         8: }
         9:
        10: void main ()
        11: {
        12:     long a = 2;
    ...
    

コマンドの概要

関連項目

WinDbg (カーネル モード) の使い方を始める

デバッガーの操作

デバッグ手法

WinDbg Windows デバッガーをダウンロードしてインストール

WinDbg の機能