}
return TRUE;
}
Zone Definitions
The sample code above registers six debug zones for the module that you can now use in conjunction with conditional statements in debugging macros. The following line of code shows one possible way to do this:
DEBUGMSG(dpCurSettings.ulZoneMask & (0x00000001<<(15)),
(TEXT("Error Information\r\n")));
If the debug zone is currently set to MASK_ERROR, the conditional expression evaluates to TRUE and DEBUGMSG sends the information to the debug output stream. However, to improve the readability of your code, you should use the DEBUGZONE macro defined in Dbgapi.h, as illustrated in the following code snippet, to define flags for your zones. Among other things, this approach simplifies the combination of debug zones through logical AND and OR operations.
#include <DBGAPI.H>
// Definition of zone flags: TRUE or FALSE according to selected debug zone.
#define ZONE_INIT DEBUGZONE(0)
#define ZONE_DEINIT DEBUGZONE(1)
#define ZONE_ON DEBUGZONE(2)
#define ZONE_FAILURE DEBUGZONE(13)
#define ZONE_WARNING DEBUGZONE(14)
#define ZONE_ERROR DEBUGZONE(15)
DEBUGMSG(ZONE_FAILURE, (TEXT("Failure debug zone enabled.\r\n")));
DEBUGMSG(ZONE_FAILURE && ZONE_ WARNING,
(TEXT("Failure and Warning debug zones enabled.\r\n")));
DEBUGMSG(ZONE_FAILURE || ZONE_ ERROR,
(TEXT("Failure or Error debug zone enabled.\r\n")));
Enabling and Disabling Debug Zones
The DBGPARAM field ulZoneMask is the key to setting the current debug zone for a module. You can accomplish this programmatically in the module by changing the ulZoneMask value of the global dpCurSettings variable directly. Another option is to change the ulZoneMask value in the debugger at a breakpoint within the Watch window. You can also control the debug zone through another application by calling the SetDbgZone function. Another option available at run time is to use the Debug Zones dialog box, illustrated in Figure 4-2, which you can display in Visual Studio with Platform Builder via the CE Debug Zones command on the Target menu.
Figure 4-2 Setting debug zones in Platform Builder
The Name list shows the modules running on the target device that support debug zones. If the selected module is registered with the Debug Message service, you can find the list of 16 zones displayed under Debug Zones. The names correspond to the selected module's dpCurSettings definition. You can select or deselect zones to enable or disable them. By default, the zones defined in the dpCurSettings variable are enabled and checked in the Debug Zones list. For modules not registered with the Debug Message service, the Debug Zone list is deactivated and unavailable.
Overriding Debug Zones at Startup
Windows Embedded CE enables the zones you specify in the dpCurSettings variable when you start the application or load the DLL into a process. At this point, it is not yet possible to change the debug zone unless you set a breakpoint and change the ulZoneMask value in the Watch window. However, CE supports a more convenient method through registry settings. To facilitate loading a module with different active debug zones, you can create a REG_DWORD value with a name that corresponds to the module name specified in the lpszName field of the dpCurSettings variable and set it to the combined values of the debug zones you want to activate. You can configure this value on the development workstation or the target device. It is generally preferable to configure this value on the development workstation because changing target device registry entries requires you to rebuild the run-time image, whereas a modification of the registry entries on the development workstation only requires you to restart the affected modules.
Table 4-3 illustrates the configuration for a sample module called ModuleName. Make sure you replace this placeholder name with the actual name of your executable file or DLL.
Table 4-3 Startup registry parameter examples
Location | Development Workstation | Target Device |
---|---|---|
Registry Key | HKEY_CURRENT_USER\Pegasus\Zones | HKEY_LOCAL_MACHINE\DebugZones |
Entry Name | ModuleName | ModuleName |
Type | REG_DWORD | REG_DWORD |
Value | 0x00000001-0x7FFFFFFF | 0x00000001-0x7FFFFFFF |
Comments | The Debug Message system uses the target-side value for a module only if the development workstation is unavailable or if the development-side registry does not contain a value for the module. |
Windows Embedded CE uses the lower 16 bits of the REG_DWORD value to define named debug zones for application debugging purposes. The remaining bits are available to define unnamed debug zones, with the exception of the highest bit, which is reserved for the kernel. Therefore, you should not set a module's debug zone value to 0xFFFFFFFF. The maximum value is 0x7FFFFFFF, which enables all named and unnamed debug zones.
The name Pegasus refers to the code name of the first Windows CE version that Microsoft released for handheld personal computers and other consumer electronics in 1996.
Best Practices
When working with debug messages, keep in mind that heavy use of debug messages slows down code execution. Perhaps even more important, the system serializes the debug output operations, which can provide an unintentional thread synchronization mechanism. For example, multiple threads running unsynchronized in release builds might cause issues not noticeable in debug builds.
When working with debug messages and debug zones, consider the following best practices:
■ Use Conditional statements Use debug macros with conditional statements based on debug zones. Do not use DEBUGMSG(TRUE). Also avoid using retail macros without conditional statements, such as RETAILMSG(TRUE), although some model device driver (MDD)/platform dependent driver (PDD) drivers must use this technique.
■ Exclude debugging code from release builds If you only use debug zones in debug builds, include the global variable dpCurSettings and zone mask definitions in #ifdef DEBUG #endif guards and restrict the use of debug zones to debug macros (such as DEBUGMSG).