Debug Zones: Eliminating Excess Chatter


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:


http://blogs.msdn.com/ce_base/archive/2006/12/18/debug-messages-and-debug-zones-in-windows-ce.aspx


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:


<Link to DebugZone.zip>


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


[HKEY_CURRENT_USER\Pegasus\Zones]


"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.


<Link to DebugZone.zip>


The list of modules I call SetDbgZone on:






            {L"filesys.dll",     0},


            {L"kitl.dll",        1},


            {L"relfsd.dll",      4},


            {L"FSDMGR.DLL",      2},


            {L"osaxst0.dll",0x8000},


            {L"osaxst1.dll",0x8000},


 


            {L"relfsd.dll",      4},


 


           {L"devmgr.dll",      1},


           {L"diskcache.dll",   4},


           {L"mspart.dll", 0x8000},


           {L"pcibus.dll",      1},


           {L"pm.dll",          1},


           {L"exfat.dll",       2},


           {L"atapi.dll",  0x2000},


           {L"busenum.dll",     1},


 


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”


Best Practices


 


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.

Summary


 


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!


 

DebugZone.zip

Comments (1)
  1. Some additional tips that I think could be usefu to enable debug zones on drivers/modules provided in binary only-format:

    • You can also enable/disable debug zones on the device registry file using [HKLMDebugZones] and the same syntax and names of the Pegasus key. If you do that to reduce the amount of messages, I think it’s better to do that on a specific device and not for all the devices you’re working on (like you do from the PC registry) because you may risk to miss some messages that are "chatter" on a device but critical information on another one. If you "forget" the settings inside the  PC registy (and you’ll do that if you are debugging at late evening  or early morning!), some time later you may not understand why a message that’s enabled in the dbgzones initialization isn’t displayed.
    • to get the module name you can use the debug shell. Type "gi mod" or "gi proc" to have the module/process id and then use "zo" command to retrieve the module name (and zones list). I think that adding module name to the debug zones dialog could be a good idea for the next QFEs 🙂

    • you can access a module’s debug zones only if it has been loaded and this will made the "zo" method non applicable for modules (drivers) that fails during the initialization phase.

    To retrieve their debug zones you may build a very simple exe that simply calls LoadLibrary to load the driver as a DLL.

    Then you’ll be able to use the shell commands on it.

    • If it won’t load even inside the very simple app, it is likely missing some other DLLs

    To find them you can use dependency walker (http://www.dependencywalker.com/).

    The PE executable format is shared between CE and the "desktop" versions of Windows and this tool can be helpful to find missing DLLs.

    You should notice that it will search DLLs recursively and if you have a DLL on the desktop that has the same name of a CE one it may report wrong dependencies for that module.

    Try to solve dependencies one level a time, reopening the CE version of each module that you have to analyze.

    I hope that those suggestions are useful even if written in my very poor english!

    I hope that not being such a good developer made me a good debugger, at least 🙂

    I would like to see more information about debugging on CE-related blogs and docs since applying the right debugging techniques could really shorted development time.

    I did some training courses here in Italy and I found that many developers don’t know (and use) all the debugging tools that CE provides and use mostly "brute force" (OutputDebugString) or "trial and error" debugging, losing a lot more time than that needed to enable KITL on their devices and learn how to leverage the power of the debugger and debugging tools.

    This is, of course, MVHO.

Comments are closed.

Skip to main content