Developing Drivers with the Windows Driver Foundation (Pro Developer)
WinDbg is used in distinctly different ways for UMDF drivers and KMDF drivers. However, several basic WinDbg features and practices apply to both UMDF and KMDF drivers, as described in this section.
Note In Windows Vista and later versions, most debugging tools-including WinDbg-must run with elevated privileges. The simplest way to do this is to right-click the WinDbg icon and click Run as administrator. All instructions to run WinDbg in this chapter assume that you will run WinDbg with elevated privileges in Windows Vista.
Checked versus Free Builds
The Build utility supports two types of build: checked and free. WinDbg can be used with either build type, but checked builds are usually preferred for debugging because:
-
Most compiler optimization is disabled, which makes it easier to trace problems.
-
Debugging-specific code such as the ASSERT macro is enabled.
Performance is the main shortcoming of checked builds, so they are typically used during the earlier stages of the development cycle when eliminating bugs is the primary concern. Tasks such as performance tuning and final testing must be performed on a free build of Windows and typically are not done until the end of the development cycle, after most driver bugs have been eliminated. WinDbg is still used to debug any issues that arise during this phase of testing, but free builds are more difficult to work with and bugs are typically harder to locate and fix during the late phases of testing.
The driver and Windows are not required to be the same build type. You can run checked driver builds on a free build of Windows, or vice versa. Retail versions of Windows are free builds of the operating system, but checked builds of Windows are available to MSDN subscribers.
Tip | Checked builds of Windows are useful for the early stages of debugging drivers. However, the most important practice for finding driver bugs is to always enable Driver Verifier. |
Info See "Using Checked Builds of Windows" on the WHDC Web site for information about obtaining and using checked builds-online at http://go.microsoft.com/fwlink/?LinkId=79304.
User Interface
WinDbg has a menu and associated toolbar for performing tasks such as setting up and starting a debugging session, stepping through source code, setting breakpoints, and so on. One key part of the UI is a collection of windows, which can be displayed by clicking the View menu. The most important one is the Command window, which is displayed by default. It shows information about the ongoing debugging session and allows you to run debugger commands and extensions. Figure 22-1 shows the WinDbg UI from a debugging session with the Fx2_Driver sample.
The Command window is open by default and is where you do most of the debugging work. The upper pane displays data such as the register values and assembly code that is generated as you step through the driver code. The lower pane supports a command-line interface that can be used to run debugger commands and extensions. You can use the cursor to highlight and copy text from either pane and paste it into a WinDbg command line. For example, the data that some WDF debugger extension commands display includes suggested command-line strings that retrieve related information. To obtain the information, just paste the string into the lower pane and run it.
The other windows display detailed information and must be explicitly opened by using the View menu. Figure 22-1 shows two of them: a Locals window that displays the values of local variables for the currently executing routine and a source code window that can be used to view and step through the driver's source code. Other WinDbg windows include the following:
Watch window | Tracks the values of specified variables. |
Call Stack window | Displays call stack information. |
Registers window | Tracks the contents of registers. |
Debugger Commands
Some debugging tasks can be done through the GUI. However, it is limited to relatively simple procedures like stepping through source code or issuing a Break instruction. A much more powerful set of tools is available through the Command window's lower pane, which can be used to run debugger commands and extensions.
WinDbg comes with a set of standard debugger commands. Some duplicate the functionality of the GUI, but many perform tasks or provide detailed information about various aspects of the driver that cannot be done any other way. Some examples of debugger commands are shown in Table 22-1.
Type | Commands | Description |
---|---|---|
Stack frame | k and related commands | Displays a thread's stack frame and some related information. |
Breakpoint | bp and related commands | Can be used to set breakpoints in running drivers, list the current breakpoints, set breakpoints for modules that have not yet been loaded, and so on. |
Memory | d and related commands | Displays the contents of memory, subject to constraints such as the range, display format, mechanism used to specify the memory location, and so on. |
Step | p and related commands | Steps through the driver code. |
Trace | t and related commands | Traces through the driver code. |
Go | g | Breaks out of the debugger and returns the driver to normal operation. |
Tip See "Debugger Commands" in the Debugging Tools for Windows help file for a complete list of WinDbg commands.
Symbols and Source Code
Symbol files are essential for effective debugging. They contain information about an executable file, including the names and addresses of functions and variables. The symbols for UMDF and KMDF drivers are in a product data base (.pdb) file. This file is produced by the Build utility when the project is compiled and placed in the project's output folder.
If you are having difficulty getting WinDbg to work correctly-for example, seeing an incorrect stack or incorrect local variable values-a likely cause is missing or incorrect symbol files. To work properly, WinDbg must have the correct symbol files. In particular, the symbols must be from the same build that produced the driver. For example, WinDbg cannot use the symbols from a free build to debug a checked build of a driver. The symbol files are different, even if they were produced from exactly the same source files.
Tip | The compiler optimizations used with free builds can sometimes cause WinDbg to show incorrect values for local variables, even with the correct symbols. |
You must explicitly specify the location of your driver's symbol files by adding the folder to the WinDbg symbol search path list.
To Specify a Driver's Symbol Path
-
On the WinDbg File menu, click Symbol File Path.
-
In the Symbol Search Path dialog box, add the folder that contains the driver symbols to the list. Separate multiple symbol folders with a semi-colon (;).
-
Check Reload to force WinDbg to reload the symbols, and click OK.
Note You can reload symbols by running the ld debugger command in the WinDbg Command window.
You must also explicitly provide WinDbg with the path to the Windows symbol files. As with drivers, the Windows symbols must exactly match the operating system build.
You can download Windows symbols from Microsoft and set the path, as described earlier in this chapter. However, getting the correct set of symbol files can sometimes be difficult. The preferred way to get Windows symbols is to direct WinDbg to the Microsoft public symbols server. WinDbg then automatically downloads the correct symbols for the build of Windows on which your driver is running.
Tip | Make sure that you have the correct symbols for your driver and Windows. The easiest way to do this is to connect WinDbg to the Microsoft symbols server at http://msdl.microsoft.com/download/symbols. |
To Instruct WinDbg to Download Symbols from the Microsoft Symbols Server
-
Run the following debugger command:
-
.symfix+
-
This debugger command appends the symbols server location to the symbol file path and downloads the appropriate PDB files.
Because the Windows symbols are tens of megabytes of data, the symbols server is practical only if you have a fast Internet connection. If you do not have a fast connection, install the symbols manually.
To Install the Windows Symbols Manually
-
Download the symbols packages from the WHDC Web site at http://go.microsoft.com/fwlink/?LinkId=79331.
To perform source-level debugging, you must also provide WinDbg with the location of the driver's source files.
To Add the Driver's Source File Folder to the WinDbg Search Path
-
On the WinDbg File menu, click Source File Path.
-
In the Source Search Path dialog box, add the driver's source folder path to the list, and click OK. Separate multiple source folders with a semicolon (;).
Debugger Extensions
Debugger extensions work much like debugger commands, but provide additional functionality, as follows:
-
WinDbg includes a standard set of debugger extensions in the Debugging Tools for Windows package.
For example, a particularly useful debugger extension is !analyze, which is used to analyze crash dumps. Some extensions work in either kernel mode or user mode, whereas others work only in a single mode.
-
WDF includes a set of debugger extensions that provide support for debugging UMDF and KMDF drivers.
The WDF extensions are summarized in Tables 22-2 and 22-3 in this section.
-
You can write custom debugger extensions if the debugger commands and extensions that Microsoft provides do not meet your requirements.
Category | Description |
---|---|
!wudfext.help | Displays all UMDF debugger extensions. |
!wudfext.dumpdevstacks | Displays device stacks in the host process. |
!wudfext.devstack | Displays a selected device stack in the host process. |
!wudfext.dumpirps | Displays the list of pending I/O request packets in the host process. |
!wudfext.umirp | Displays information about a user-mode I/O request packet. |
!wudfext.driverinfo | Displays information about a UMDF driver. |
!wudfext.wdfdevicequeue | Displays the I/O queues for a device. |
!wudfext.wdfqueue | Displays information about an I/O queue. |
!wudfext.wdfrequest | Displays information about an I/O request. |
!wudfext.wdfobject | Displays information about a UMDF object and its parent and child relationships. |
!wudfext.pnp | Displays Plug and Play and power management states. |
Category | Description |
---|---|
!wdfkd.wdfhelp | Displays all KMDF debugger extensions. |
!wdfkd.wdfcrashdump | Displays a crash dump that includes the framework's log information. |
!wdfkd.wdfdevice | Displays information that is associated with a WDFDEVICE object handle. |
!wdfkd.wdfdevicequeues | Displays information about all the queue objects that belong to a specified device. |
!wdfkd.wdfdriverinfo | Displays information about a framework-based driver, such as its run-time version and hierarchy of object handles. |
!wdfkd.wdfhandle | Displays information about a specified KMDF handle. |
!wdfkd.wdfiotarget | Displays information about a WDFIOTARGET object handle. |
!wdfkd.wdfldr | Displays all loaded KMDF drivers. |
!wdfkd.wdflogdump | Displays the framework's log information. |
!wdfkd.wdfqueue | Displays information about a WDFQUEUE object handle. |
!wdfkd.wdfrequest | Displays information about a WDFREQUEST object handle. |
Tip See "Debugger Extension API" in the Debugging Tools for Windows help file for information on how to write a debugger extension.
Debugger extensions are provided as DLLs, and WinDbg loads the standard extensions automatically. Others, including the WDF extensions, must be explicitly loaded. Debugger extension commands all start with a "!" character. They are invoked in the same way as debugger commands, by typing them in the Command window's lower pane, along with any necessary arguments.
Tables 22-2 and 22-3 list some commonly used UMDF and KMDF debugger extensions. The debugging documentation includes a complete reference for debugger commands, debugger extensions, and the API that supports custom extensions.
Note When KMDF Verifier is enabled, several of the KMDF debugger extension commands provide more information than is available otherwise. For example, !wdfdriverinfo reports leaked handles. Chapter 21, "Tools for Testing WDF Drivers," provides information about KMDF Verifier.
Inside Out | The two sets of WDF debugger extensions are packaged in separate DLLs. The UMDF debugger extensions are in WudfExt.dll, and the KMDF debugger extensions are in Wdfkd.dll. Both DLLs are included with the WDK and located under the %wdk%\bin folder. The DLLs are also included with the debugging package, under Program Files\ Debugging Tools for Windows\Winext. The WDK and Debugging Tools for Windows are released separately. |
Категории