On This Page
IntroductionOne of the best ways to find errors in a driver is to exercise more driver code during testing. Drivers commonly include code to handle rare events, such as inadequate resources or unusual failure scenarios. Testing more such code paths before releasing a driver can improve the reliability of the driver in the field. The following are several simple tips for testing more of your driver code. Use PREfast for DriversPREfast is a static code analysis tool that analyzes C code at function level. That is, it applies a set of rules to one function in the driver at a time, verifying that the flow of control within the function conforms to the rules. Although PREfast does not perform live, operational tests, it is nevertheless useful in identifying code paths that contain potential errors. PREfast can find attempts to use uninitialized variables, failures to release resources such as memory and locks, and failures to check function return values. The Windows Server SP1 DDK contains a version of PREfast that includes driver-specific rules, along with a reference guide and a "Getting Started" document. Simulate Low Resource ConditionsWindows provides two simple ways to test driver operation in low resource conditions:
Driver Verifier (verifier.exe) includes an option to simulate low resource conditions. You can enable the Low Resources Simulation option on the Driver Verifier command line or through the Driver Verifier Manager. When this option is enabled, Verifier causes randomly selected memory allocations to fail, beginning at least seven minutes after system startup. (If you enable the option without rebooting, fault injection starts approximately seven minutes later.) The seven-minute delay avoids fault injection during boot itself and thus provides a more realistic low-resource scenario. These randomly injected memory allocation faults provide a way to test a driver's response to low-memory conditions and to exercise related code. Because the faults occur randomly and therefore can affect any part of your driver, you can test many code paths in a short period of time. Another way to simulate low-memory conditions is to change system boot parameters to limit the amount of memory available to Windows. Keep in mind, however, that many drivers fail soon after startup when system memory is severely restricted. Consequently, this method tests a more limited number of code paths. On Windows XP and later systems, use Bootcfg to add the /burnmemory parameter to an entry in the boot.ini file. When the /burnmemory parameter is enabled, some physical memory is reserved so that it is unavailable to the system. For example, the following reduces the amount of memory on the system by 896 megabytes: bootcfg /raw "/burnmemory=896" /A /ID 1 In the preceding Bootcfg command, the /raw switch adds the contents of the string "/burnmemory=896" to a boot entry. The /A switch appends the string to the existing entry, rather than replacing all boot parameters for the entry. The /ID switch identifies the boot entry. On Windows 2000 systems, use Bootcfg to add the /maxmem parameter to an entry in the boot.ini file. The /maxmem parameter limits the amount of memory to a specified value. To add the /maxmem parameter, use the /MM switch in Bootcfg. For example: bootcfg /addsw /MM 256 /ID 1 This command uses the Bootcfg /addsw (add switch) switch with the /MM argument and a value of 128 to add the /maxmem parameter and to set it to a value of 128, thus limiting to 128 MB the amount of memory available to Windows. The /ID switch identifies the boot entry. Simulate Other ErrorsYou can simulate other types of failures by including driver-specific code that an external application can use to signal an error. One simple technique is to define an I/O control code (IOCTL) that a user-mode test application can send. When the driver receives the IOCTL, it exercises the code related to the error. Such IOCTLs can be as numerous or as complicated as required to test the relevant driver code. For example, to test code paths related to disk corruption, the IOCTL might specify a driver-defined function code for disk error testing, with specific error data included in the input buffer. The driver's DispatchDeviceControl routine parses the control code and the contents of the buffer to determine exactly which error conditions to test, sets up any additional data required for testing, and then calls the corresponding error-handling routine in the driver. In addition, the driver must perform security checks on each incoming IOCTL request. The DispatchDeviceControl routine must ensure that each incoming request matches the complete IOCTL definition and that the caller has adequate privileges to perform the requested operation. You can also use the Device Path Exerciser's Active Control Test option to test the DispatchDeviceControl routine itself. Use Device Path ExerciserThe Device Path Exerciser (dc2.exe) utility is provided with the WDK. Device Path Exerciser tests a driver's robustness by rapidly sending thousands of similar calls to the driver. The calls request I/O operations with varying access methods, buffer lengths, addresses, and parameters - some are valid, but many are not. The tests ensure that the driver responds correctly to the requests, either by returning valid data or by failing the request appropriately, without causing a system crash, corrupting the memory pool, or leaking memory. Device Path Exerciser can help you find driver errors related to:
On Windows XP and later systems, you can use the Active Control Test feature of Device Path Exerciser together with driver-defined IOCTLs to test specific IOCTL code paths. To use this feature, you create a list of driver-specific IOCTLs for Device Path Exerciser to send to the driver. The list must appear in an ASCII text file and must be formatted in the same way as entries in the DC2WMIParser log file. The Active Control Test sends many similar DeviceIoControl requests to the driver, specifying the I/O control codes (no FSCTLs) in the input file and varying those I/O control codes to include randomly generated function codes and function codes that are numerically above, below, and between those listed in the input file. The device types, buffer lengths, addresses, and buffer contents also vary in these requests, so that the DispatchDeviceControl routine and any related error handling code can be thoroughly tested. Monitor Code Coverage during TestingTo determine how much of your driver code is being exercised, build in ways to monitor the number of times particular code paths are executed. Here are some simple techniques:
Use Code Coverage ToolsThird-party code coverage tools are also available. You can find such tools by searching for "Windows driver code coverage" in your favorite Internet search engine. Microsoft does not endorse any particular tools. Microsoft is investigating the addition of code coverage techniques to Driver Verifier and other driver testing tools. In addition, Windows Hardware Quality Labs (WHQL) started a pilot code coverage program in December 2003 for kernel-mode drivers that do not fit into any of the current "Designed for Windows" logo programs. Participation is limited to 100 drivers, and drivers must meet certain criteria. For details, see the WHQL and Windows Logo Program Testing News for March 1, 2004. ResourcesMicrosoft Windows Driver Development Kit (DDK) In the DDK documentation, see the following sections:
In the DDK installation directory, see the following files for information about PREfast:
Microsoft Hardware and Driver Developer Information |