What is the difference between RETAILMSG and DEBUGMSG? This question comes up once in a while, so I thought it might be interesting to discuss it.
The first thing that we should think about is what are these? The first clue, assuming that we don’t read the documentation, is that they are both in all capital letters. This is usually a clue that they are macros. If they are macros, they cannot be hidden away in a binary, they must be in a header file that we can look at to figure out what they do. If I didn’t like you so much, I would just stop here and let you go off and search for them to figure them out.
HINT: A search of the Public tree would take a long time, but since sysgen puts the header files that we need in our OSDesign or PBWorkspace folder we can search there and save a lot of time. Search in the WINCE<version>\<BSP specific folder>\cesysgen sub folder.
After searching for RETAILMSG, you should find that it is defined in dbgapi.h. Now we have a way to see what they do. You will notice that it looks something like this:
                This is a ship build
                Define DEBUGMSG and RETAILMSG so that they don’t do anything
    #ifdef DEBUG
                This is a debug build
                Define DEBUGMSG so that it outputs if the condition is met
                This is a retail build
                Define DEBUGMSG and RETAILMSG so that they don’t do anything
   For both debug and retail builds do this
    Define RETAILMSG so that it outputs if the condition is met
This means that the important difference between RETAILMSG and DEBUGMSG is the conditions that allow or exclude them from outputting their messages.
When defined to output messages, both RETAILMSG and DEBUGMSG will output the message if the first parameter, the condition, is true. Where they output the message is up to you. If you are using KITL, they will output on the KITL transport once the connection is established. If you are not using KITL or if the connection has not been established they will output using the HAL OEMWriteDebugString() function. OEMWriteDebugString() can be implemented in different ways on different platforms, but usually it will output on a serial port.
The second parameter of both RETAILMSG and DEBUGMSG are the variable argument list to be passed to NKDbgPrintfW. Because this is a macro, this parameter must be wrapped in a parenthesis which are part of the argument. The arguments for NKDbgPrintfW are similar to printf, except that the format string is a wide character string. This means that the format string must be qualified by using a macro that changes the char string to a wide character string. I prefer the TEXT() macro for this, but there are other ways.

Copyright © 2008 – Bruce Eitman
All Rights Reserved