DbgPrint output in Vista
I’ve been tasked with updating our kernel mode driver to build off the Server 2008 WDM and run in Vista. Updating to the 2008 WDM was relatively painless. There were a couple of new deprecated functions but the adjustments weren’t hard to make. So, I set up a Vista virtual machine for debugging, attached WinDbg to it, and fired up our service. To my dismay, none of the DbgPrint() statements that the driver outputs were being shown in WinDbg! Without debugging output it is almost impossible to debug a device driver. A little bit of digging online lead me to a great device driver blog: A Hole In My Head
It turns out Vista maps every call to DbgPrint() to the newer DbgPrintEx() function.
ULONG DbgPrint( IN PCHAR Format,. . . . [arguments]);
IN ULONG ComponentId,
IN ULONG Level,
IN PCHAR Format,
. . . . [arguments]
DbgPrint is supposed to work just like the printf function except it writes to output to any debugger that is attached. You would pass in a format string followed by a valist of arguments and it would write it out a debugger. DbgPrintEx works to same way, but added two new arguments with the intention of filtering the system output. The ComponentID specifies the type of driver that is writing the output. The possible values are:
The Level argument rates the messages severity on a scale of 0-31. This way the host operating system, and ultimately the person debugging, can decide which messages it wants to see.
Now, when Vista encounters a call to DbgPrint() it maps it to DbgPrintEx() with the DEFAULT ComponentID. The set behavior for DEFAULT DbgPrint messages is to hide them. There are three ways to change this. One way is to go through your source code an change all the DbgPrints to DbgPrintExs with the ComponentID that most closely matches the device. Unfortunately this function is only supported in XP or later, so this may not be possible for all drivers. The other two solutions involve changing the output settings in Vista.
Attach a debugger (KD or WinDbg) and break the machine right after boot. Enter the command ‘ed nt!Kd_DEFAULT_MASK 0x0F’ into the debugger. This will allow all types of DbgPrint output to be shown. This is not a persistent solution so you will have do it every time you run the VM.
On the Vista virtual machine, open the registry and add the value “DEFAULT” : REG_DWORD : 0xFFFFFFFF to the key “HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter” The next time you reboot the system it will output all of the DbgPrint output.
So that mystery is solved. Now I just need to use my debugging output to figure out why my driver throws a kernel exception and blue screens my VM…