Developing Drivers with the Windows Driver Foundation (Pro Developer)
UMDF drivers are user-mode DLLs that are hosted in an instance of WUDFHost. The debugging techniques are thus similar to those used with services. Setting up debugging is much simpler than for kernel-mode drivers. In particular, both WinDbg and the target driver can be on the same computer. This section discusses how to prepare the system and start a debugging session.
Note Before you can start debugging, you must install the driver and the debugging tools on a computer running the target version of Windows.
Chapter 20, "How to Install WDF Drivers," provides more information on how to install UMDF drivers.
How to Enable Debugging of Driver Load and Startup Code
You start the debugging process by attaching WinDbg to the instance of WUDFHost that hosts the driver. This causes the process to break into the debugger and allows you to do such tasks as setting breakpoints in one or more driver methods. However, the driver load and startup code is executed shortly after the driver manager runs WUDFHost, before you can typically attach WinDbg to the process.
To enable you to debug driver load and startup code, WDF provides a registry value that can be set to instruct each new instance of WUDFHost to delay executing this code long enough to allow you to attach a debugger to WUDFHost. Then you can set breakpoints and debug the load and startup code.
To Set the Delay Time for WUDFHost
-
Run RegEdit.exe.
-
Find the WUDFHost key, , as follows:
HKEY_LOCAL_MACHINE\ SOFTWARE\Microsoft\Windows NT\CurrentVersion\ WUDF\Services\{}
The key's HostProcessDbgBreakOnDriverLoad value-which is set to 0 by default-specifies how many seconds WUDFHost should delay before starting to load a driver.
-
Change the value to a convenient time delay, such as 0xF (15 seconds).
HostProcessDbgBreakOnDriverLoad is sufficient for debugging most load and startup issues. However, it does not delay the execution of DllMain. If you need to debug DllMain or the initialization of any global variables, you should instead set the HostProcessDbgBreakOnStart value. This value instructs WUDFHost to delay executing any driver code for a specified time. The procedure for setting HostProcessDbgBreakOnStart is exactly the same as for HostProcessDbgBreakOnDriverLoad.
You can also set the high bit for either registry value. In that case, if the framework does not successfully break into the user-mode debugger within the specified delay time, the framework then attempts to connect to a kernel-mode debugger.
Tip | After you have finished debugging the load and startup code, be sure to delete the HostProcessDbgBreakOnDriverLoad or HostProcessDbgBreakOnStart value from the registry. Otherwise, every UMDF driver on the system will continue to load slowly. |
How to Start Debugging a UMDF Driver's Driver Load and Startup Code
After you have specified the delay time, you can start debugging.
To Debug a Driver's Driver Load and Startup Code
-
Disable the driver. For USB devices such as the OSR USB Fx2 device, just unplug the device. For other devices, use Device Manager to disable the driver.
-
Set the HostProcessDbgBreakOnDriverLoad value to give you enough time to attach WinDbg to WUDFHost.
-
Run Task Manager and click the Processes tab.
This tab displays all instances of WUDFHost and the process identifier (PID) of each instance.
Note Task Manager does not show WUDFHost instances or PIDs by default. Select Show processes for all users to instruct Task Manager to display WUDFHost instances and use the View menu to instruct Task Manager to display PIDs.
-
Click the Image Name header control to list the WUDFHost instances near the top of the window, where they are readily visible.
-
Open a command window.
-
Type the following partial command and press the spacebar-but do not press ENTER.
WinDbg -p
-
Start the driver load process.
For USB devices, such as the Fx2 device, just insert the device into the computer. For other devices, use Device Manager to enable the driver.
-
Watch Task Manager until a new instance of WUDFHost appears in the list.
-
Add the PID for that new WUDFHost instance to complete the command you began entering in Step 6, and then press ENTER. You must have a space between "-p" and the PID.
Important | You must complete steps 6 and 9 before the delay specified by HostProcessDbgBreakOnDriverLoad has elapsed. |
This procedure attaches the debugger to the new WUDFHost process, which breaks into the debugger before the driver load and startup code has been called. You can now use WinDbg to set one or more breakpoints in the driver's load or startup code before running the g command to let WUDFHost continue. See "UMDF Walkthrough: Debugging the Fx2_Driver Sample" later in this chapter for a detailed example of how to use this procedure.
To Debug a Driver's DllMain Function
-
Set the HostProcessDbgBreakOnStart value to give you enough time to attach WinDbg to WUDFHost.
-
Attach WinDbg to the appropriate WUDFHost process, as described in the preceding procedure.
-
After WUDFHost breaks into the debugger, run the following command to instruct WUDFHost to break into the debugger when the driver DLL is loaded into memory:
-
sxe ld DriverName.dll
-
-
Run the g command to let WUDFHost continue.
After WUDFHost loads the driver into memory, it breaks into the debugger and you can set breakpoints on the driver's DllMain function or any global initialization code that you want to debug.
How to Start Debugging a Running UMDF Driver
If you do not need to debug the load and startup code, you can simply attach WinDbg to the appropriate instance of WUDFHost. However, systems can have multiple instances of WUDFHost, so there is no simple way to determine which instance of the process hosts the driver that you want to debug. Use the following procedures to find the correct instance of WUDFHost and attach WinDbg to the process.
To Identify the Appropriate Host Process for Debugging a UMDF Driver
-
Run Task Manager and click the Processes tab to display the currently running instances of WUDFHost.
-
Open a command window.
-
Run the Tlist tool against the PID of the first instance of WUDFHost, by using the following command:
-
tlist processID
The Tlist tool provided with the Debugging Tools for Windows package lists all of the DLLs that have been loaded by the process specified by processID.
-
-
Examine the list of DLLs to see whether it includes the driver you want to debug.
If not, repeat step 3 for each instance of WUDFHost listed in Task Manager until you identify the correct one.
-
Note the PID of the instance of WUDFHost that includes the driver that you want to debug.
To Attach WinDbg to the Host Process From the Command Line
-
Run WinDbg from a command window with the PID of the appropriate WUDFHost instance.
To Attach WinDbg to the Host Process From Within WinDbg
-
Run WinDbg, and then, on the File menu, click Attach to a Process.
-
Select the appropriate instance of WUDFHost, and then click OK to attach WinDbg to the process.
How to Track UMDF Objects and Reference Counts
A common problem with COM-based programs is failure to correctly manage reference counts. In general, reference count bugs can be very difficult to locate. However, UMDF simplifies the process for UMDF drivers by supporting object and reference count tracking.
Object and reference count tracking is controlled by two values in the WUDFHost registry key: TrackObjects and TrackRefCounts. Both are set to 0 by default, which disables the features. To enable object tracking, set TrackObjects to 1. If you discover a memory leak, set TrackRefCounts to 1, which allows you to view the history of reference count adds and releases.
Tip | Reference count tracking significantly degrades performance. Set TrackRefCounts to 1 only when you need to debug a memory leak. Otherwise, the value should be set to 0. |
If one of the driver's objects has a nonzero reference count when the driver unloads, the framework breaks into the debugger. You can then use the UMDF !dumpobjects debugger extension to dump the driver's outstanding objects.
You are not required to wait for the framework to break into the debugger before using this procedure. You can use !dumpobjects to view a driver's outstanding objects and reference counts at any time.
Two optional registry values can be added to the WUDFHost key if the default values are not appropriate:
-
MaxRefCountChangesTracked By default, UMDF tracks a maximum of 256 reference count changes for an object.
If you need to track a larger number of reference count changes, set MaxRefCountChangesTracked to an appropriate value.
-
MaxStackDepthTracked By default, 16 frames is the maximum stack depth that UMDF tracks.
If you need to track a larger number of stack frames, set MaxStackDepthTracked to an appropriate value.
How to Start Debugging a UMDF Driver Crash
A misbehaving UMDF driver cannot cause a system crash, but the driver can still crash its WUDFHost process. This is sometimes referred to as a "driver stop." If a debugger is attached to the process, the process breaks into the debugger and you can debug the crash dump directly. The most useful tool for this purpose is the !analyze debugger extension command. UMDF also creates a crash dump file that can be analyzed later. It is stored at %WINDIR%\System32\Logfiles\Wudf.
Tip See "User-Mode Dump Files" in the Debugging Tools for Windows help file for information on how to analyze crash dump files.
UMDF also has integrated verification code-called UMDF Verifier-that is always enabled. If a driver uses the UMDF DDI incorrectly or passes incorrect parameters, UMDF Verifier generates a driver stop. If a debugger is attached, you can debug the crash dump immediately or you can analyze the crash dump file later. UMDF Verifier can also be configured to create a Windows error report.
Chapter 21, "Tools for Testing WDF Drivers," provides more information on UMDF Verifier.
Категории