Debug or Not Debug

August 25th, 2006 - Fernando Roberto

Here is a very simple thing to do. Generating conditional compilation using the pre-processor along with the DBG symbol has to be a simple task. Just as the _DEBUG symbol is defined by the projects written in C/C++ in Visual Studio, DBG symbol is defined by DDK to inform you that the current build is Checked or Free. Thus, we can illustrate with a simple code snippet as it follows below:

//-f--> I'm thinking it's easy...
#ifdef DBG
   DbgPrintf("Checked Version\n");
#else
   DbgPrintf("Free Version\n");
#endif

The code above will display the message “Checked Version” when the build is done in Checked and “Free Version”, when the build is done in Free, right?

WRONG!!! That’s it, wrong! The DBG symbol is defined as 1 in checked builds and set to 0 in free builds. Thus, we have DBG = 1 for Checked builds and DBG = 0 for Free builds. The way it is, the code above still displays the message “Checked Version”, even when compiled as Free. This is because the DBG symbol is still set, it is set to 0, but it is defined in either way. So, to adequately test this condition, we must do it with #if in place of #ifdef, as it follows below:

//-f--> OK, now it will display the correct build configuration
#if DBG
   DbgPrintf("Checked Version\n");
#else
   DbgPrintf("Free Version\n");
#endif
 
//-f--> Testing only for Free builds
#if !DBG
   DbgPrintf("Free Version\n");
#endif

To facilitate debugging, it is not rare to see some drivers with the code that, when compiled in Checked, interrupts its execution using the following code:

//-f--> Interrupt the execution only in checked version
#if DBG
   __debugbreak();
#endif

If the build test was incorrect here, we would have a beautiful blue screen whether the code above went to the production. As you may know, calling breakpoints in code throw exceptions that would be handled by the debugger, but if the debugger is not attached to the system, HORRIBLE THINGS WILL HAPPEN.

In the file there ntddk.h, there is a shown macro below that helps to test the build conditions in Checked.

#if DBG
    #define IF_DEBUG if (TRUE)
#else
    #define IF_DEBUG if (FALSE)
#endif

In this way the syntax below is quite clear:

IF_DEBUG
{
   __debugbreak();
}

Since we are talking about conditional builds, we may also have to build specialization in SOURCES file. DDKBUILDENV environment variable is set to “che” when the build is done in Checked, or it is set to “fre” when in Free builds. So we can, for example, using different paths for libs, in accordance with the current build configuration.

!if "$(DDKBUILDENV)" == "fre"
BUILD_CONFIG=Release
!else
BUILD_CONFIG=Debug
!endif
 
TARGETLIBS=.\Lib\$(BUILD_CONFIG)\HtsCpp.lib

Leave a Reply