One of WinDbg's strengths is that its capabilities can be expanded by writing custom extension commands. This can be quite convenient, particularly for formatting the display of driver-specific data structures. This section explains the process of adding extension commands to WinDbg. How WinDbg Extensions WorkA WinDbg extension is just a user-mode DLL that exports various commands in the form of DLL functions. The extension DLL also contains several support routines that perform initialization and version-checking operations. The linkage between target system memory (whether crash file dump or a live target) is established with callback routines that the extension DLL uses to reference the debug target. This means the DLL has the same view of the target system's memory as WinDbg. In particular, extension commands cannot reference memory that was paged out at the time a crash or breakpoint occurs. Initialization and Version-Checking FunctionsTo write an extension DLL for WinDbg (or NTSD or KD, for that matter), two DLL export functions are required for initialization. Optionally, a third version-checking function can be provided. These functions are described below. WinDbgExtensionDllInitWinDbg calls this function when the user loads the extension DLL. Its job is to save the address of the callback table so that other parts of the DLL can use it. This function (described in Table 17.3) is required.
ExtensionApiVersionWinDbg calls this function when it attempts to load an extension DLL. Its purpose is to validate version compatibility between WinDbg and the extension. It does this by returning a pointer to the version structure associated with the extension DLL. This function (shown in Table 17.4) is required.
CheckVersionEach time WinDbg executes a command in the DLL, it calls this function before calling the command routine. CheckVersion's job is to ensure that the version of the extension DLL is compatible with the version of Windows 2000 being debugged. If not, an error message should inform the user of the problem. The function (described in Table 17.5) is optional.
Writing Extension CommandsEach command in an extension DLL is implemented as a separate function. A macro, DECLARE_API, facilitates the declaration of each extension function. DECLARE_API( command_name ) { // // code goes here... // ... } DECLARE_API provides the function with the prototype shown in Table 17.6. The names of commands must be provided in complete lowercase; otherwise WinDbg cannot find them.
The work that an extension command might perform is boundless. Any operation that makes debugging easier, such as formatting and displaying driver-specific data structures, is appropriate. If an extension command takes (or could take) a long time to execute, or if considerable output is involved, it should periodically check to see if the WinDbg user has typed Ctrl-C. Otherwise, the user has no way to interrupt the command. One of the WinDbg helper functions described in the next section performs this check. WinDbg Helper FunctionsAn extension DLL gains access to the system being debugged by invoking helper functions exported by WinDbg. These functions also provide access to the WinDbg command window for input and output. Table 17.7 contains a brief description of these helper functions.
The documentation for these helper functions is contained within the DDK help files. Look for the section entitled "Routines Called From Debugger Extensions." Building and Using an Extension DLLA WinDbg extension is just a user-mode DLL, and, therefore, Visual Studio is an appropriate vehicle for its construction. Interestingly, because a driver-specific extension relies on driver structures (and perhaps some DDK structures), some unusual #include statements appear. Otherwise, the build process is quite routine for an extension DLL. To load and use an extension DLL with WinDbg, it must be loaded using the !load command. After that, the commands are directly accessible by preceding them with a bang (!), using the form !command. The !unload command allows the unloading of an extension DLL. WinDbg allows up to 32 extension DLLs to be loaded simultaneously. When executing a !command, WinDbg searches DLLs starting with the most recently loaded. Thus, it is possible to override the functionality of an existing extension command.
|