HomeQuestions and AnswersArticlesSamplesLibrariesForumsNewsLinks

STLogFile - easy way to trace debug info

By Nicholas Tsipanov, September 02, 2002.

Introduction

There are several problems connected with Smartphone 2002 applications debugging. First of all, there is a class of programs that cannot be debugged at all since you cannot attach to a process under Windows CE. For example, consider a today plug-in or a device driver. Another problem is that debugging through a serial or USB cable is really slow.

An application log solves those problems. Also it helps to diagnose customer side problems. This article explains using log files and gives a powerful free log file library for Windows CE.

Download

Preface

TRACE(..), TRACE(..), TRACE(..).. How often do you write these statements in your MFC application? And how much time did you spend running your program under debugger? It gets really boring to wait while this program starts, "synchronized exception information" (hey, I don't use exceptions in my program!), and finally starts.... Yes, buying a network CF card would eliminate this waiting, but what would you do if your application fails only on your customer site (well, what's he doing to my program?) and you cannot find out the solution until you run your program under debugger in the conditions your program has on customer's site? The answer is as simple as programming (kidding) and as old as programming (kidding again). Logging!

STLogFile

Here we present you a simple solution which enables you to easily add logging to your project. It has some additional features, which make this piece of code not only a logging tool but a debugging and a profiling one. To make a long story short here we will shortly describe its usage and it is for you to decide if this code is worth anything or not.

Installation

What? I n s t a l l a t i o n??? No, no installation. Simply put your copy of STLogFile.h into a directory where you code can reach it via #include and that's it. Working directory is a the perfect place to put it but you may have a kind of shared include directory for you project and then it would be better to put the STLogFile.h there. After that add the #include "stlogfile.h" line into the sources where you are going to use it and you're ready. As to me, I prefer to include it into the "stdafx.h" since it is guaranteed that it will be defined already in any .cpp file where I want to use it (unless you don't use precompiled headers, but in this case you know what to do).

Logging macros

STLOG_WRITE

This is the main macro, which caused this article to be written. It has TRACE usage semantics (or printf if you know what does it mean):

STLOG_WRITE(_T("the line to be logged, string: %s, number: %d"), szString, nNumber);

STLOG is the synonym for STLOG_WRITE for short. There is an option (STLOG_USE_FOR_TRACE - see below) for the log file to use it instead of TRACE macros.

STLOG_MARKER

If you want to mark every enter and exit of the code block you can use STLOG_MARKER macro:

{ STLOG(_T("Statistics calculations")); ...your code here... }

This will print >>>[Statistics calculations] and <<<[Statistics calculations] every time the execution reaches this piece of code. More common using of this macro is marking function executions:

int MyClass::MyFunction() { STLOG_MARKER(_T("MyClass::MyFunction")); if (moon_phase == moon_full) return 1; if (moon_phase == moon_new) return 2; return 3; }

This will print entering markings for this function on enter and exit wherever the execution leaves this code.

STLOG_WRITE_DATA

char Buffer[435]; FillTheBuffer(Buffer, 435); STLOG_WRITE_DATA(Buffer, 435);

What can be more simple?

Debugging macros

At the moment we have only one macro that could fit this section, if you have any ideas, please share them with us.

STLOG_LASTERROR

Whenever you call a system function that can fail you can print out what caused the problem:

HANDLE hFile = CreateFile(....); if (INVALID_HANDLE == hFile) { STLOG_WRITE("Cannot open file"); STLOG_LASTERROR; }

And you will have a textual description of the problem in the log file.

Profiling macros

Before describing the log file profiling features it would be appropriate to say that all measured timing include time for file operation, which slightly increases execution time, therefore this method could only help to *estimate* and compare execution times to find bottlenecks of your code.

STLOG_PROFILE_FUNCTION

... STLOG_PROFILE_FUNCTION(Calculate()); ...

This code will estimate the time needed for function execution. Simple. When the logging is turned off this will be transformed to straight call to Calculate().

STLOG_PROFILE_BLOCK

{ STLOG_PROFILE_BLOCK; .. code here ... }

This sample of code prints to log file the time when the execution entered to the profiled block, when the execution leaves it and the time interval between the two points. When your program finishes, this macro will print profiling statistics, like how many times this code has been executed, how much time did it take in total, in average, maximium and minimum timings.

STLOG_PROFILE_CHECKPOINT

Sometimes you want to have intermediate timings and STLogFile has a solution for this case:

{ STLOG_PROFILE_BLOCK; Phase0(); STLOG_PROFILE_CHECKPOINT Phase1(); STLOG_PROFILE_CHECKPOINT Phase2(); }

This will print timings between the check points and the time from beginning of the block every time execution reaches any check point.

Options

To make the logfile flexible (different projects have different requirements for logging) we made some kind of fine tuning preferences.

STLOG_DEBUG

This is the first and the main option for the log file. To turn the logging off put comment markings to the line that defines it, and your logging will be turned off.

STLOG_CREATE_NEW

If you want every start to create a new log file then use this define. New log files will have names like <executable>XX_log.txt, where XX is some number. Otherwise it will always use the name <executable>_log.txt for log files.

STLOG_CREATE_FILE_IN_THE_SAME_DIRECTORY

If you want to have a log file in the same directory where your executable is then leave this define. Otherwise the log file will be created in the root folder. For desktop systems this means the root directory of the disk where your executable is located.

STLOG_PRINT_COMPILE_INFO

This will print in log file the file name and a line number where STLOG_WRITE macro has been encountered. I didn't find this macro useful and it's commented by default.

STLOG_USE_FOR_TRACE

TRACEs will be printed to the log file.

Conclusion

Occasionally log files are the only way to debug the code and every developer reinvents the wheel for this task. It might be useful to have a common way to do it. I hope this article would help Windows developers to save some time on it.

Discuss

Discuss this article. Here you can write your comments and read comments of other developers.

  © 2002 Smartphone Developer Network | Want to be an author? | Contact Us