Windows デバッガー (WinDbg) は、Windows 用デバッグ ツールに含まれるカーネル モードおよびユーザー モードのデバッガーです。 この記事では、カーネル モード デバッガーとして WinDbg の使用を開始するのに役立つ演習を提供します。
WinDbg を取得するには、「 Windows デバッガー (WinDbg) をダウンロードしてインストールする」を参照してください。
カーネル ]モードのデバッグを設定する
A kernel-mode debugging environment typically has two computers, the host computer and the target computer. デバッガーはホスト コンピューター上で実行され、デバッグ対象のコードはターゲット コンピューター上で実行されます。 ホストとターゲットはデバッグ ケーブルで接続されます。
Windows デバッガーでは、次の種類のケーブルがサポートされています。
- Ethernet
- USB 3.0
- Serial (also called null modem)
速度と信頼性を確保するには、イーサネット ケーブルとローカル ネットワーク ハブを使用する必要があります。 次の図は、イーサネット ケーブルを使用してデバッグ用に接続されたホストコンピューターとターゲット コンピューターを示しています。
以前のバージョンの Windows のオプションは、シリアル ケーブルなどの直接ケーブルを使用することです。
目的の構成のセットアップ手順に従って、プロセスを開始します。
ホスト コンピューターとターゲット コンピューターを設定するには、「 カーネル モード デバッグを手動で設定する」を参照してください。
デバッガーを Hyper-V 仮想マシン (VM) に接続するには、「 仮想マシン ホストのネットワーク デバッグの設定 - ネットワーク経由のカーネル デバッグ (KDNET)」を参照してください。
カーネルモード デバッグ セッションを確立する
ホストとターゲット コンピューターを設定し、デバッグ ケーブルで接続したら、カーネルモードデバッグ セッションを確立できます。
セットアップ プロセスに使用した記事の手順に進みます。 たとえば、カーネル モード デバッグ用のイーサネット ケーブルを使用してデバッグするホストコンピューターとターゲット コンピューターを設定する場合は、「 KDNET ネットワーク カーネルデバッグを自動的に設定する」の手順に従います。
WinDbg でデバッグを開始する
デバッグ セッションでの WinDbg の使用を開始するには、次の手順に従います。
ホスト コンピューターで WinDbg を開き、ターゲット コンピューターとのカーネルモード デバッグ セッションを確立します。
Open the debugger documentation CHM (.chm) file by selecting Help>Contents.
デバッガーのドキュメントは、Windows 用デバッグ ツールでもオンラインで入手できます。 詳細については、「 Windows デバッガーのインストール」を参照してください。
カーネルモード デバッグ セッションを確立する際、WinDbg が自動的にターゲット コンピューターを中断する可能性があります。 If WinDbg doesn't break in, select Debug>Break.
WinDbg ウィンドウの下部にあるコマンド ラインで、次のコマンドを実行します。
.sympath (Symbol Path) コマンドを使用してシンボル パスを設定します。
.sympath srv*
出力は次の例のようになります。
Symbol search path is: srv* Expanded Symbol search path is: cache*;SRV*https://msdl.microsoft.com/download/symbols
The symbol search path tells WinDbg where to look for symbol program database (PDB) files (.pdb). デバッガーには、関数名や変数名など、コード モジュールに関する情報を取得するためのシンボル ファイルが必要です。
Run the .reload command so WinDbg starts finding and loading symbols files.
.reload
View a list of loaded modules with the lm command.
lm
出力は次の例のようになります。
0:000>3: kd> lm start end module name fffff800`00000000 fffff800`00088000 CI (deferred) ... fffff800`01143000 fffff800`01151000 BasicRender (deferred) fffff800`01151000 fffff800`01163000 BasicDisplay (deferred) ... fffff800`02a0e000 fffff800`03191000 nt (pdb symbols) C:\...\ntkrnlmp.pdb fffff800`03191000 fffff800`03200000 hal (deferred) ...
Start the target computer running again with the g (Go) command.
g
Break in to the target computer again by selecting Debug>Break.
dt (Display Type) コマンドを実行し、
nt
モジュールで_FILE_OBJECT
データ型を調べます。dt nt!_FILE_OBJECT
出力は次の例のようになります。
0:000>0: kd> dt nt!_FILE_OBJECT +0x000 Type : Int2B +0x002 Size : Int2B +0x008 DeviceObject : Ptr64 _DEVICE_OBJECT +0x010 Vpb : Ptr64 _VPB ... +0x0c0 IrpList : _LIST_ENTRY +0x0d0 FileObjectExtension : Ptr64 Void
x (シンボルの検査) コマンドを実行し、
nt
モジュールのシンボルの一部を確認します。x nt!\*CreateProcess\*
出力は次の例のようになります。
0:000>0: kd> x nt!*CreateProcess* fffff800`030821cc nt!ViCreateProcessCallbackInternal (<no parameter info>) ... fffff800`02e03904 nt!MmCreateProcessAddressSpace (<no parameter info>) fffff800`02cece00 nt!PspCreateProcessNotifyRoutine = <no type information> ...
bu (ブレークポイントの設定) コマンドと bl (ブレークポイント リスト) コマンドを実行して、ブレークポイントを設定および確認します。
bu
コマンドを使用し、Windows 呼び出しでMmCreateProcessAddressSpace
ルーチンにブレークポイントを設定します。 次に、bl
コマンドを実行し、ブレークポイントが設定されていることを確認します。bu nt!MmCreateProcessAddressSpace bl
出力は次の例のようになります。
0:000>0: kd> bu nt!MmCreateProcessAddressSpace 0: kd> bl 0 e fffff800`02e03904 0001 (0001) nt!MmCreateProcessAddressSpace
g
(Go) と入力して、ターゲット コンピューターを実行します。g
Windows が
MmCreateProcessAddressSpace
ルーチンを呼び出すと、ターゲット コンピューターがデバッガーに割り込まれます。ターゲット コンピューターがデバッガーにすぐに中断されない場合は、ターゲット コンピューターでいくつかのアクションを実行します。 たとえば、メモ帳を開き、ファイルを保存します。
.reload
および k (Display Stack Backtrace) コマンドを使用してスタック トレースを表示します。.reload k
出力は次の例のようになります。
0:000>2: kd> k Child-SP RetAddr Call Site ffffd000`224b4c88 fffff800`02d96834 nt!MmCreateProcessAddressSpace ffffd000`224b4c90 fffff800`02dfef17 nt!PspAllocateProcess+0x5d4 ffffd000`224b5060 fffff800`02b698b3 nt!NtCreateUserProcess+0x55b ... 000000d7`4167fbb0 00007ffd`14b064ad KERNEL32!BaseThreadInitThunk+0xd 000000d7`4167fbe0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
Select View>Disassembly. Then select Debug>Step Over (or select F10).
Enter step commands a few more times as you watch the output in the Disassembly window.
bc (ブレークポイントクリア) コマンドを使用してブレークポイントをクリアします。
bc *
g
(Go) と入力して、ターゲット コンピューターを実行します。g
To break in again, select Debug>Break, or select CTRL-Break.
View a list of all processes with the !process command:
!process 0 0
出力は次の例のようになります。
0:000>0: kd> !process 0 0 **** NT ACTIVE PROCESS DUMP **** PROCESS ffffe000002287c0 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 001aa000 ObjectTable: ffffc00000003000 HandleCount: <Data Not Accessible> Image: System PROCESS ffffe00001e5a900 SessionId: none Cid: 0124 Peb: 7ff7809df000 ParentCid: 0004 DirBase: 100595000 ObjectTable: ffffc000002c5680 HandleCount: <Data Not Accessible> Image: smss.exe ... PROCESS ffffe00000d52900 SessionId: 1 Cid: 0910 Peb: 7ff669b8e000 ParentCid: 0a98 DirBase: 3fdba000 ObjectTable: ffffc00007bfd540 HandleCount: <Data Not Accessible> Image: explorer.exe
ffffe00000d52900
などのプロセスのアドレスをコピーし、!process
コマンドを使用してプロセス情報を表示します。<process-address>
部分をプロセス アドレスに置き換えます。!process <process-address> 2
ffffe00000d52900
プロセスの出力には、プロセス内の次のスレッドが表示されます。0:000>0:000>0: kd> !process ffffe00000d52900 2 PROCESS ffffe00000d52900 SessionId: 1 Cid: 0910 Peb: 7ff669b8e000 ParentCid: 0a98 DirBase: 3fdba000 ObjectTable: ffffc00007bfd540 HandleCount: Image: explorer.exe THREAD ffffe00000a0d880 Cid 0910.090c Teb: 00007ff669b8c000 ffffe00000d57700 SynchronizationEvent THREAD ffffe00000e48880 Cid 0910.0ad8 Teb: 00007ff669b8a000 ffffe00000d8e230 NotificationEvent ffffe00000cf6870 Semaphore Limit 0xffff ffffe000039c48c0 SynchronizationEvent ... THREAD ffffe00000e6d080 Cid 0910.0cc0 Teb: 00007ff669a10000 ffffe0000089a300 QueueObject
Copy the address for a thread, such as
ffffe00000e6d080
, and view the thread information with the !thread command.<thread-address>
部分をスレッド アドレスに置き換えます。!thread <thread-ddress>
ffffe00000e6d080
スレッドの出力には、次の概要情報が表示されます。0: kd> !thread ffffe00000e6d080 THREAD ffffe00000e6d080 Cid 0910.0cc0 Teb: 00007ff669a10000 Win32Thread: 0000000000000000 WAIT: ... ffffe0000089a300 QueueObject Not impersonating DeviceMap ffffc000034e7840 Owning Process ffffe00000d52900 Image: explorer.exe Attached Process N/A Image: N/A Wait Start TickCount 13777 Ticks: 2 (0:00:00:00.031) Context Switch Count 2 IdealProcessor: 1 UserTime 00:00:00.000 KernelTime 00:00:00.000 Win32 Start Address ntdll!TppWorkerThread (0x00007ffd14ab2850) Stack Init ffffd00021bf1dd0 Current ffffd00021bf1580 Base ffffd00021bf2000 Limit ffffd00021bec000 Call 0 Priority 13 BasePriority 13 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5 ...
View all the device nodes in the Plug and Play device tree with the !devnode command:
!devnode 0 1
出力は次の例のようになります。
0:000>0: kd> !devnode 0 1 Dumping IopRootDeviceNode (= 0xffffe000002dbd30) DevNode 0xffffe000002dbd30 for PDO 0xffffe000002dc9e0 InstancePath is "HTREE\ROOT\0" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe000002d9d30 for PDO 0xffffe000002daa40 InstancePath is "ROOT\volmgr\0000" ServiceName is "volmgr" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) DevNode 0xffffe00001d49290 for PDO 0xffffe000002a9a90 InstancePath is "STORAGE\Volume\{3007dfd3-df8d-11e3-824c-806e6f6e6963}#0000000000100000" ServiceName is "volsnap" TargetDeviceNotify List - f 0xffffc0000031b520 b 0xffffc0000008d0f0 State = DeviceNodeStarted (0x308) Previous State = DeviceNodeStartPostWork (0x307) ...
!devnode
コマンドを使用して、デバイス ノードとそのハードウェア リソースを表示します。!devnode 0 9
出力は次の例のようになります。
0:000>... DevNode 0xffffe000010fa770 for PDO 0xffffe000010c2060 InstancePath is "PCI\VEN_8086&DEV_2937&SUBSYS_2819103C&REV_02\3&33fd14ca&0&D0" ServiceName is "usbuhci" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) TranslatedResourceList at 0xffffc00003c78b00 Version 1.1 Interface 0x5 Bus #0 Entry 0 - Port (0x1) Device Exclusive (0x1) Flags (0x131) - PORT_MEMORY PORT_IO 16_BIT_DECODE POSITIVE_DECODE Range starts at 0x3120 for 0x20 bytes Entry 1 - DevicePrivate (0x81) Device Exclusive (0x1) Flags (0000) - Data - {0x00000001, 0x00000004, 0000000000} Entry 2 - Interrupt (0x2) Shared (0x3) Flags (0000) - LEVEL_SENSITIVE Level 0x8, Vector 0x81, Group 0, Affinity 0xf ...
!devnode
コマンドを使用して、サービス名が "disk" のデバイス ノードを表示します。!devnode 0 1 disk
出力は次の例のようになります。
0: kd> !devnode 0 1 disk Dumping IopRootDeviceNode (= 0xffffe000002dbd30) DevNode 0xffffe0000114fd30 for PDO 0xffffe00001159610 InstancePath is "IDE\DiskST3250820AS_____________________________3.CHL___\5&14544e82&0&0.0.0" ServiceName is "disk" State = DeviceNodeStarted (0x308) Previous State = DeviceNodeEnumerateCompletion (0x30d) ...
!devnode 0 1
コマンドの出力には、ノードの物理デバイス オブジェクト (PDO) のアドレスが表示されます。Copy the address of a PDO, such as
0xffffe00001159610
, and view the PDO details with the !devstack command.<PDO-address>
部分を PDO 情報に置き換えます。!devstack <PDO-address>
PDO
0xffffe00001159610
スレッドの出力には、次のデバイス スタックが表示されます。0:000>0: kd> !devstack 0xffffe00001159610 !DevObj !DrvObj !DevExt ObjectName ffffe00001d50040 \Driver\partmgr ffffe00001d50190 ffffe00001d51450 \Driver\disk ffffe00001d515a0 DR0 ffffe00001156e50 \Driver\ACPI ffffe000010d8bf0
Get information about the disk.sys driver object with the !drvobj command and the driver name "disk":
!drvobj disk 2
出力には、ドライバー オブジェクトに関する詳細情報が表示されます。
0:000>0: kd> !drvobj disk 2 Driver object (ffffe00001d52680) is for: \Driver\disk DriverEntry: fffff800006b1270 disk!GsDriverEntry DriverStartIo: 00000000 DriverUnload: fffff800010b0b5c CLASSPNP!ClassUnload AddDevice: fffff800010aa110 CLASSPNP!ClassAddDevice Dispatch routines: [00] IRP_MJ_CREATE fffff8000106d160 CLASSPNP!ClassGlobalDispatch [01] IRP_MJ_CREATE_NAMED_PIPE fffff80002b0ab24 nt!IopInvalidDeviceRequest [02] IRP_MJ_CLOSE fffff8000106d160 CLASSPNP!ClassGlobalDispatch [03] IRP_MJ_READ fffff8000106d160 CLASSPNP!ClassGlobalDispatch ... [1b] IRP_MJ_PNP fffff8000106d160 CLASSPNP!ClassGlobalDispatch
!drvobj
コマンドの出力には、CLASSPNP!ClassGlobalDispatch
などのディスパッチ ルーチンのアドレスが表示されます。 次のコマンドを使用して、ClassGlobalDispatch
ルーチンでブレークポイントを設定して確認します。bu CLASSPNP!ClassGlobalDispatch bl
g
(Go) と入力して、ターゲット コンピューターを実行します。g
Windows が
ClassGlobalDispatch
ルーチンを呼び出すと、ターゲット コンピューターがデバッガーに割り込まれます。ターゲット コンピューターがデバッガーにすぐに中断されない場合は、ターゲット コンピューターでいくつかのアクションを実行します。または、メモ帳を開き、ファイルを保存します。
次のコマンドを使用してスタック トレースを表示します。
.reload k
出力は次の例のようになります。
2: kd> k Child-SP RetAddr Call Site ffffd000`21d06cf8 fffff800`0056c14e CLASSPNP!ClassGlobalDispatch ffffd000`21d06d00 fffff800`00f2c31d volmgr!VmReadWrite+0x13e ffffd000`21d06d40 fffff800`0064515d fvevol!FveFilterRundownReadWrite+0x28d ffffd000`21d06e20 fffff800`0064578b rdyboost!SmdProcessReadWrite+0x14d ffffd000`21d06ef0 fffff800`00fb06ad rdyboost!SmdDispatchReadWrite+0x8b ffffd000`21d06f20 fffff800`0085cef5 volsnap!VolSnapReadFilter+0x5d ffffd000`21d06f50 fffff800`02b619f7 Ntfs!NtfsStorageDriverCallout+0x16 ...
qd (Quit and Detach) コマンドを使用して、デバッグ セッションを終了します。
qd
コマンドのまとめ
この記事で説明するコマンドの詳細については、次のリンクを参照してください。
- .sympath (シンボル パスの設定)
- .reload (モジュールの再読み込み)
- x (シンボルの検証)
- g (Go)
- dt (型の表示)
- lm (読み込まれたモジュールの一覧表示)
- k (スタック バックトレースの表示)
- bu (ブレークポイントの設定)
- bl (ブレークポイントの一覧)
- bc (ブレークポイントのクリア)
- !process
- !thread
- !devnode
- !devstack
- !drvobj
- qd (終了してデタッチ)
For more information about menu commands like Debug>Break and Help>Contents, see the Get started with WinDbg (user-mode) article.