After getting a lot of feedback for the “Introduction to WinDBG” article I posted a few weeks ago, I thought I’d follow it up with another in the series, this time about Driver Verifier. All driver developers need to know a few basic things about the tools of the trade, and one of the most important tools for driver development that Microsoft ships is Driver Verifier.
Driver Verifier is essentially a library of routines that cross-check your interaction with the OS in a stricter way than normal. The design philosophy of the operating system is that kernel-mode components should trust one another. This works well in practice, as it provides significant performance improvements on often-used code paths. However, ithis trust is exactly what you don’t want during driver development, as it can let subtle errors go unnoticed until your software is in your customers’ hands.
There are a couple of tools designed to enforce stricter checking in the OS. One of these tools, the checked build, I’ll talk about in another article. Driver Verifier is the other major runtime driver validation tool. Verifier ships with the operating system, and changes with each release. The configuration interface is presented in a user-mode GUI app, but the code that does the real work is embedded in ntoskrnl. Also, note that Verifier and the checked build are unrelated; you really need both, but you can use either alone.
Verifier can catch tons of little errors once you turn it on. It can check for proper use of IRQLs and spin locks, proper implementation of the DMA protocol, correct handling of IRPs, and so on. It can even test your driver in a low-memory simulation, randomly failing memory allocation requests. Best driver development practice dictates that all development testing be done with full driver verifier turned on (possibly with the exception of low resources simulation). By following this rule, you’re sure to catch as many mistakes as possible, before they are covered up by more layers of your code. In fact, one developer at Microsoft told me that he routinely runs the entire OS under verifier.
The description that follows is done on the current 64-bit XP preview release, but other OSes are similar. To enable this magic, it’s easiest to start verifier.exe from the Start->Run box. Although there is another registry-based way to configure verifier, I won’t go into it here – operate Regmon if you’re curious. Choose “Create custom settings” and click Next, and “Select individual settings from a list”, and Next. At this point, you’re prompted with a list of verifications. The easiest and most comprehensive thing is to check them all, but you may want to leave low resources simulation off the list during development and early testing. Also, IRQL checking has a sizeable performance impact, due to the fact that it invalidates all pageable pages in the driver before each call into your code. Still, this is an invaluable test, particularly in combinationwith the PAGED_CODE macro. Once you finish with options, you are prompted to select which drivers to verify.
Once verification is started on your driver, be sure to have a kernel debugger hooked up, as any violations that Verifier finds will turn into breaks into the debugger. If you don’t have a debugger attached, the system will just bugcheck with verifier’s own bugcheck code. Usually, verifier is pretty clear about what has gone wrong with your driver, so the problems (if not the fixes) are pretty obvious. In my experience, Verifier doesn’t catch many false positives – if Verifier breaks in, there is a very high probability that you have a real bug, and you should fix it.
One other thing – I occasionally find drivers that have clearly not been tested against verifier, because they trip it off during whole system verification. If you find one of these drivers, be a good citizen and drop a friendly note to the company that is responsible for it. Bug reports from clueful developers are always appreciated. And, if that doesn’t work, there’s always public shame. 🙂