Developing complex applications involves a large amount of time spent on bug crushing. Even after you think that everything is OK- and pass to the final release - the software might throw some surprise errors invisible while debugging. So a developer should again use all available tools and instruments to find out the problem.
Runtime project tracing is one of the simple and useful things which allow us to see what actually happens - dead locks, racing and other smart bugs
I present here an easy to use runtime trace tool that can be compiled into your own C++ project. It allows you to use the Release binaries and still get runtime trace as long as you want. Then just rebuild your project to purge out all the runtime trace. With that, you will decrease code size and improve application execution speed.
From now, you will be able to forget about commenting dozens of your runtime trace operator lines!
- How can I use '
fprintf' style formatted debug logs?
- How will I erase (comment out) these lines from the source code, then add them again when the bug returns?
- What log file name convention should I use to get different logs for another project without editing code?
These and other question now have a positive answer. Let's look through the code!...
Using the code
To use the code, you should do these steps:
- add these files: DbgLogger.cpp, DbgLogger.h, DbgLoggerCfg.h to your C++ project
- add to the .cpp file under the debug include statement:
- use '
fprintf' style operator
DBG_PRN(.); for tracing (instead of point, use a format specifier and arguments, of course)
DbgLoggerCfg.h is supplied ready to use for runtime trace. When you decide to purge trace statements out, you should just comment the
#define DBG_INFO line out and then rebuild your project. It is possible to use Unicode character trace. Look for the
#define DBG_INFO_WCHAR line.
The last thing of the description but the most important one - where should you look for the recently created log file?
The log file is situated under the long and common Windows application path: C:\Documents and Settings\<your logged name>\Local Settings\Application Data\<your application name>\Log\<your application name>.log.
The next example shows a typical runtime trace usage:
int _tmain(int argc, _TCHAR* argv)
void* aPtr = (void*)argv;
" String = '%s'\n"
" Integer = '%d'\n"
" HexItegerString = '0x%04X'\n"
" Pointer = '%p'\n\n",
"This is the String",
Behind the stage
The source code is included. Let's have a look at it.
The main part of the code is the template class that allows the usage of
wchar_t as the base string item and exports the
void Out( const CharType* pFmt, ... ) function.
template< class CharType >
void Out( const CharType* pFmt, ... )
#define DBG_PRN g_db.Out line allows us to use global class member functions just like ordinary ones.
Purging from binaries allows
#define DBG_PRN( A ) ; with
#pragma warning (disable:4002). The last one just turns an annoying compiler warning message off.
Points of Interest
This article describes some preprocessor tricks that allows us to make project debugging much easy.