Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / MFC
Article

Function Calling Sequence Tracer Class

Rate me:
Please Sign up or sign in to vote.
4.56/5 (14 votes)
15 Aug 20032 min read 64K   1.1K   23   11
A class to trace the sequence at which functions are called.

Sample image

Introduction

Sometimes in complex applications large number of messages are to be processed and there are a large number of functions for handling requests and events. Sometimes it is confusing to see what are the functions called by a given function. What are the functions that will lead to a call to a particular function. What is the sequence of calling of all these functions. If some programmer is supposed to continue an unfinished work of another programmer, in a badly documented system it will be a nightmare. Even the same programmer who had previously made all this can be confused. I experienced this problem in one of my projects. I searched for a solution on the Internet but I was unlucky, so I started to do it myself. I wrote a class to trace methods in the application and log all the sequence to a file in a readable format.

The idea

The idea of my solution is to use a global object of a small class having some static member functions and static member variables. In an early point in the application (in the constructor of the application class, for example) we specify the file that will hold the sequence log. This is done using a static function. The class contains some private static member variables to maintain the current level of the call. At the beginning of a function an instance of this class is instantiated in the stack using the constructor, which takes as a parameter the text that should be logged. At the end of the function, this class instance will be out of scope so the destructor of the class will be called and the level will decrease.

Implementation

The following is the header file of the SequenceTracer class:

// SequenceTracer.h

#ifndef _SEQUENCE_TRACER
#define _SEQUENCE_TRACER

#include <fstream>  // for std::ofstream


class SequenceTracer  
{
public:
    static void Start(const char * fileName); // Set the file name and start
    SequenceTracer(const char * text); // The only constructor
    virtual ~SequenceTracer();
protected:
    static int Stack[256]; // The stack maintaing sequence numbers
    static int Level; // The current level in the stack
    static std::ofstream * OutStream; // The always open output stream

};

#endif //_SEQUENCE_TRACER

And this is the implementation file for the class:

// SequenceTracer.cpp

#include "SequenceTracer.h"
//////////////////////////////////////////////////////////////////////
int SequenceTracer::Level;
std::ofstream * SequenceTracer::OutStream;
int SequenceTracer::Stack[256];
//////////////////////////////////////////////////////////////////////
void SequenceTracer::Start(const char *fileName)
{
    OutStream = new std::ofstream (fileName);
}
//////////////////////////////////////////////////////////////////////
SequenceTracer::SequenceTracer(const char * text)
{
    if (!OutStream) // Outstream should be initialized
        return;

    for (int i = 0; i < Level; i++)
        *OutStream << '\t'; // Make indentation

    Stack[Level]++; // Increment the sequence number

    for (i = 0; i < Level, Stack[i] > 0; i++)
        *OutStream << Stack[i] << '.'; // Print the sequence number

    *OutStream << " "; // Add a space
    *OutStream << text << "\n"; // Write the text followed by newline
    Level++; // Increase the level
}
//////////////////////////////////////////////////////////////////////
SequenceTracer::~SequenceTracer()
{
    Stack[Level] = 0; // Reset the sequence number
    Level--; // Decrease the level
    if (Level < 0) // If we are finished
    {
        delete OutStream; // Write to the file and delete stream
        OutStream = 0; // Reset the stream pointer
    }
}
//////////////////////////////////////////////////////////////////////

Using the class

Using this class is very easy simply in three steps:

  1. Include the SequencTracer.h in CPP files in which you want to trace function sequence
  2. In an early point in the application (The application constructor for example) call the static function Start and give this function the name of the file to be created and will store all the sequence
  3. In the beginning of any function you would like to figure out the usage, instantiate an object of the class in the stack

After you run the application and the level is less than 0, you can see the contents of the sequence file. It will look like:

Sample image

I made an application specially to test the class. I made two helper macros to further simplify using the class:

#ifdef _DEBUG
#define SEQ_TRACE(txt) SequenceTracer unique_variable_name##__LINE__ (txt)
#define SEQ_START(fileName) SequenceTracer::Start(fileName)
#else
#define  SEQ_TRACE(txt)
#define SEQ_START(fileName)
#endif
// Thanks to Michael Dunn for ##__LINE__

History

  • 16-8-2003: Article submitted, minor updates.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Chief Technology Officer www.mmonem.com
Egypt Egypt
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralUse this tool, Auto display Function Calling Sequence Pin
autodebug3-Feb-04 20:33
autodebug3-Feb-04 20:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.