Posted by Riki June
Last December Travis wrote an entry on Debug Zones, I’d like to follow this up with some practical examples. If you haven’t read his article, then I’d recommend you start there:
To highlight his points, this document takes you though turning off as much debug chatter during boot as reasonable, but without modifying source code. Because, repeat after me: modifying the $(WINCEROOT)/private/ source code is a Bad Thing.
Step 1: Insert DLL Names in Pegasus
The easiest step is to add any module names into [HKEY_CURRENT_USER\Pegasus\Zones] on your development PC. This often works; as well behaved modules will have the same Debug Zone name as their filename. The .zip file in the link below contains a the DebugZone.reg file for your Desktop PC, which contains some module names I use in my development image:
Step 2: Insert Debug Names into Pegasus
Strictly speaking these Debug Zone names have to match the name the module registered, and (unfortunately) some modules register a different name to their filename. To find the right Debug Zone name, do a search in ‘sources’ files for the dll name, then search within that directory for ‘dpCurSettings’. For MDD/PDD devices Windows Desktop Search can be a blessing.
I would like to draw your attention to some instances from the above .reg file, whose Debug Zone do not match the module name:
; Set the following modules to only display ZONE_ERROR messages
"keybddr"=dword:00008000 ; kbdmouse.dll
"NLED"=dword:00000001 ; nleddrvr.dll
"PCCARD"=dword:00000001 ; pcc_serv.dll
"GWE Server"=dword:00000000 ; gwes.exe
"iphlapi"=dword:00000000 ; iphlpapi.dll
"DEVLOAD"=dword:00000001 ; udevice.exe, devmgr.dll
"Serial"=dword:00008000 ; com16550.dll
"Common Controls"=dword:00000001 ; commctrl.dll
"HDStub"=dword:00008000 ; hd.dll
"NB"=dword:00008000 ; netbios.dll
"USB HCD"=dword:00004000 ; ohci2.dll
"SMB_SERVER"=dword:00000002 ; smbserver.dll
"TCP/IP"=dword:00008000 ; tcpstk.dll
"VEM"=dword:00000001 ; veim.dll
"NDISPower"=dword:00008000 ; ndispwr.dll
"FATFS"=dword:00000002 ; exfat.dll
"WinInet"=dword:00008000 ; httplite.dll
"MGDI Driver"=dword:00000001 ; ddi_flat.dll
The Early boot process:
Nk.exe and kernel.dll can be overridden at ‘make image’ time in your config.bib in CE6, like so:
nk.exe:initialOALLogZones 00000000 00000001 FIXUPVAR
kernel.dll:initialKernelLogZones 00000000 00000000 FIXUPVAR
To override the Debug Zone in a module as it loads, however, requires the registry APIs to be available which in turn requires the file system (filesys.dll) be loaded. Any file loaded before this cannot be overridden as it is loaded.
To override Debug Zones using the Development PC, the Release File System (relfsd.dll) must also be available.
In theory any modules loaded after FileSys can have their Debug Zone overridden at load time. Unfortunately modules loaded in Stage One boot, before the HIVE Registry goes read-write, ignore the Debug Zone that is set. So the net result is all files loaded in Stage One boot must have their debug zone overridden after they have loaded…
Step 3: Calling SetDbgZone()
To do this, I have written a little application you can add to your project. The application is launched as early as possible and iterates though the loaded modules calling SetDbgZone() on modules you specify. This application can be added to your project.reg with ‘#ifdef DEBUG’ style guards.
The list of modules I call SetDbgZone on:
What is Left?
Using the above application and .reg keys, you can go further and turn off all zones, and, in theory, there should be no messages. But sadly this is not the case. Some modules use DEBUGMSG(1 to output messages, which means you cannot turn them off. This is a bad practice to have in your drivers, and is something we are working towards removing in the Windows CE code.
A special case is the module loading code which outputs the message you will be familiar with:
"OSAXST1: %soading Module '%S' (0x%08X) at address 0x%08X-0x%08X in Process '%s' (0x%08X)\r\n”
This leads to best practices for Debug Zone use:
- Do NOT use DEBUGMSG(1
- Try to avoid RETAILMSG(1, although with some MDD/PDD drivers this cannot be avoided
- If you wish to have RETAILMSGs: place your declaration of dpCurSettings and ZONE_* inside ‘#ifndef SHIP_BUILD’ guards, rather than ‘#ifdef DEBUG’ and use RETAILREGISTERZONES() to replace DEBUGREGISTER().
- Where possible, set your drivers Debug Zone Name to the file name.
- Set the default zones for your drivers to ZONE_ERROR and ZONE_WARNING
- When bringing up a new platform, also turn on ZONE_INIT
- ZONE_ERROR should only be used when you driver is disabling significant functionality due to incorrect configuration, otherwise use ZONE_WARNING to indicate an issue which the driver is able to recover from.
- Your driver should be able to load without any ZONE_ERROR or ZONE_WARNING messages, if configuration correctly. In an ideal world, these two zones would be synonymous with your compliers error and warning messages.
These techniques can be employed to help reduce the boot chatter for developers. We still recommend you spend some time looking though these messages before you ship your device to ensure they don’t highlight something more sinister.
Have I missed some standard modules you use? Please post them in the comments so others can use them!