A lot of developers have a great experience with KMDF, but then they sometimes hit a wall. They add a chunk of code and the drivers start failing because something in the new code was not implemented correctly. The first question that comes to mind is "how do I figure out what went wrong?"
The framework team realized that this would be a very common occurrence so we made it a policy to log (using WPP) every error returned by the framework. WPP is cool technology, but if you don't have an application listening to the logger, the log entries are lost. Furthermore, if there is a crash, it is hard to get at the log itself. To solve these 2 issues, KMDF keeps a history of each driver's log. The history is about 100 entries long (you can specify a longer history using the registry).
First you need to load the KMDF debugger extension, wdfkd.dll. The debugger packages that you download from WHDC contain a copy of this DLL, but they are usually out of date. The DLL is also shipped as a part of the KMDF distribution and the WDK. You should use distribution/WDK version of the DLL for now until things stabilize and both the debugger and WDK eventually ship with the same DLL. Here are the steps you should follow to view the log:
Before we proceed, there are a few generic substitutions that you will have to make when running these commands. Each substitution phrase is in <term>. It is up to you replace these phrases with the appropriate values on your installation.
For V1.0 and V1.1 you will also need to make sure your driver's symbols are loaded since the debugger extension needs to resolve a symbol in your driver. V1.5 removes this requirement and you just need to have KMDF symbols setup properly.
2) Loading the correct wdfkd.dllTo load the correct version of wdfkd.dll you need to specify the fully qualified path to the DLL. For v1.0 and v1.1, it is <DDK-root>\wdf\kmdf10\bin\<arch>, where <arch> in this case is the machine type which is running the debugger (vs the machine being debugged). Here is how I load the extension on my machine:
0:000> !load c:\WinDDK\wdf\KMDF10\bin\x86\wdfkd.dll
1: kd> !load c:\WinDDK\5461\bin\x86\wdfkd.dll
If you are having issues with which version is being loaded you have a couple of options. The first is to execute the .chain command in the debugger. This will list all loaded extensions. You can look through the list and see if there is more then one version of wdfkd.dll loaded. Second, you can copy the DDK/WDK version of the DLL over the debugger's version of the DLL. If you choose this option, you should make a backup copy of the original DLL.
For v1.1 and v1.5 the !wdftmffile command should be used instead instead.
Here are examples of all 3 variations, notice that I am using the fully qualified path name when executing the command and that the command echoes back the path.
1: kd> !c:\WinDDK\wdf\KMDF10\bin\x86\wdfkd.wdfsearchpath c:\WinDDK\wdf\KMDF10\symbols\x86fre\wdf\tmf
wdftrace: searchpath is: c:\WinDDK\wdf\KMDF10\symbols\x86fre\wdf\tmf
1: kd> !c:\WinDDK\wdf\KMDF10\bin\x86\wdfkd.wdftmffile c:\WinDDK\wdf\KMDF10\symbols\x86fre\wdf\tmf\wdf01001.tmf
Set TMF file name is : 'C:\WinDDK\wdf\KMDF10\symbols\x86fre\wdf\tmf\wdf01001.tmf
1: kd> !c:\WinDDK\5461\bin\x86\wdfkd.wdftmffile C:\WinDDK\5461\tools\tracing\i386\wdf01005.tmf
Set TMF file name is : 'C:\WinDDK\5461\tools\tracing\i386\wdf01005.tmf'
1: kd> !c:\WinDDK\wdf\KMDF10\bin\x86\wdfkd.wdflogdump osrusbfx2
Trace searchpath is: c:\WinDDK\wdf\KMDF10\symbols\x86fre\wdf\tmf
Trace format prefix is: %7!u!: %!FUNC! -
Log at a400b000
Gather log: Please wait, this may take a moment (reading 4032 bytes).
% read so far ... 10, 20, 30, 40, 100
There are 47 log entries
--- start of log ---
1: FxPkgPnp::PnpEnterNewState - WDFDEVICE 0x5BFF06B8 !devobj 0xA400F128 entering PnP State WdfDevStatePnpInit from WdfDevStatePnpObjectCreated
2: FxPkgPnp::Dispatch - WDFDEVICE 0x5BFF06B8 !devobj 0xA400F128, IRP_MJ_PNP, 0x00000000(IRP_MN_START_DEVICE) IRP 0x87F7B5D0