Can you imagine the programming process without the possibility of debugging program code at run-time? It is obvious that such programming may exist, but programming without a debugging possibility is too complicated when we are working on big and complex projects. In addition to standard approaches of debugging program code, such as an output window on the Visual Studio IDE or the macros of asserts, I propose a new method for debugging your code: to output your debugging data to the application that is separated from the Visual Studio IDE and the project you are currently working on.
What's so good about it and should I use it?
- It's a separate module that allows you to trace and debug the release version of your project.
- It is a fully controlled module with a command set that enables you to control your debugging process: closing tracing windows (also known as trace channel), saving the entry of the trace window to the file, and so forth. Full control set are described below.
- This module supports several (the number of trace channels is unlimited) strategies of trace channels. A detailed description about trace channel is described below.
- You can easily modify this module to meet your needs.
Launch the application of trace messages catcher (next: trace catcher) before you start working with this module. Tracing data, sent to the trace catcher application, will be saved if the catcher application was inactive or was terminated during the trace operations. All the data that were saved during the critical situations, as described above, will be kept and popped-out to the trace catcher application when it starts again. There's a possibility to start the trace catcher application with the creation of the trace module and terminate it when the trace module is being destructed.
As I mentioned, this trace module allows you to put your trace data to the several output windows in the trace catcher application (next: trace channels). Trace channel is a simple window that helps to visualize your tracing data by the trace catcher application. To add your trace data to the certain trace channel, you must to describe it as follows:
_Log.setSectionName( "channel_#1" ); _Log.dump( "%s", "My trace data" );
_Log.dumpToSection( "channel_#1", "%s", "My trace data" );
If you send your trace data to the new trace channel that is not created in the trace catcher application, a new trace channel will be created automatically.
In addition to sending your trace data to the catcher, there's a possibility to manipulate the trace catcher application with commands help. Commands are divided into two parts: global commands and commands that depend on the trace channel.
Global commands affecting the whole trace catcher application:
closeRoot—closing the trace catcher application;
onTop.ON—enabling always on top state for the catcher application;
onTop.OFF—disabling always on top state for the catcher application.
_Log.sendCmd( "closeRoot" ); _Log.sendCmd( "onTop.ON")
Commands affecting certain trace channels:
clear—deleting the entry of the given trace channel;
close—closing the given trace channel;
save<path to output stream>—saving the entry of the given trace channel to the output stream that you described.
_Log.sendCmd( "Channel_1", "clear" ); _Log.sendCmd( "Channel_2", "save c:\\channel2.log" ); _Log.sendCmd( "close" ); /** close the current output window * (section) */
How to Use It
To fully use this trace module, you have to do only two steps:
- First: You must copy the [LogDispatch.dir] directory from the unzipped source file (LogDispatch_src.zip) to your project directory.
- Second: You must include the header of this module in your project modules were you want to use it.
To call all the messages described below, you must use variable names as follows: [_Log]. The trace object is created once during the project lifetime (using a singleton pattern).
Let's say calling the dump message will be described like this:
_Log.dump( "System time is %d %d %5.5f ", 15, 10, 08.555121 );
dump—Formatted trace data (sprintf format) are sent to catcher application. The tracing data will be placed to the section named as the result of calling the "setSectionName" method before that; or, if the "setSectionName" method wasn't called, tracing data will be placed to the default section named as "output@default".
dumpToSection—The principle is the same as dump message. The difference is that this message will place your data to the channel by the name that you described in this message.
setSectionName—Set the working (active) channel name.
getCmdPrefix—Sets the prefix of the command.
setCmdPrefix—Returns the prefix of the command.
sendCmd—Sends your message to the receiver application.
setCloseOnExit—Enables/disables the possibility to send the message to the catcher application on exit.
setCloseCMDOnExit—Sets the command of the catcher application that will be sent when the trace module is destroyed.
Additional operations of the module configuration
setClassNameOfCatcher—Sets the class name of the catcher application. That class name will be used in the search of the catcher application where the tracing data will be sent.
runCatcher—Executes the catcher application from the described path.
This trace module and the strategy we are using on it is a very flexible and effective trace tool for debugging big projects. In my opinion, this tool will be a very effective strategy to trace release versions of the project where all debugging data are removed. It is very easy and comfortable to use it.