04/19/2013

Track program workflow in C++

When debugging a program it can be useful to see what path the code is taking. Maybe a function is called at the wrong part in the code somehow. There are trace macros in C++ that you can use, but you can also create your own that could also provide information about the level of nesting where the function is called by indenting the debug/trace string based on the level. You could use a class to make sure that the indentation reverts to previous value when the function is finished: once the class instance runs out of scope its destructor will be called.

There must be other/better ways of doing this, but this is still better than not having anything to trace the function calls with. :)

MyTrace.h

#pragmaonce

#include<stdio.h>

class CMyTrace

{

private:

staticint m_indent;

public:

CMyTrace(LPCTSTR lpszFormat, ...);

virtual ~CMyTrace(void);

};

// If you comment this one line out then the

// debug string part won't be compiled into the project

// E.g. you could do that when compiling the release version

#define USE_CMYTRACE

#ifdef USE_CMYTRACE

#define MYTRACE CMyTrace myTrace

#else

#define MYTRACE

#endif

MyTrace.cpp

#include"StdAfx.h"

#include"MyTrace.h"

int CMyTrace::m_indent = 0;

CMyTrace::CMyTrace(LPCTSTR lpszFormat, ...)

{

TCHAR szBuffer[512];

_stprintf(szBuffer, _T("%*s"), m_indent * 2, _T(""));

::OutputDebugString(szBuffer);

va_list args;

va_start(args, lpszFormat);

int nBuf;

nBuf = _vsntprintf(szBuffer, 511, lpszFormat, args);

::OutputDebugString(szBuffer);

::OutputDebugString(_T("\n"));

va_end(args);

m_indent++;

}

CMyTrace::~CMyTrace(void)

{

m_indent--;

}

You can call the trace function at the beginning of each of your function.

STDMETHODIMP CMyAddInServer::OnActivate (VARIANT_BOOL FirstTime)

{

MYTRACE(_T("(%s, %d) %s"), _T(__FILE__), __LINE__, _T(__FUNCTION__));

// etc...

return S_OK ;

}

The result in the Output Debug window of Visual Studio would look something like this when debugging the program:

Comments

When debugging a program it can be useful to see what path the code is taking. Maybe a function is called at the wrong part in the code somehow. There are trace macros in C++ that you can use, but you can also create your own that could also provide information about the level of nesting where the function is called by indenting the debug/trace string based on the level. You could use a class to make sure that the indentation reverts to previous value when the function is finished: once the class instance runs out of scope its destructor will be called.

There must be other/better ways of doing this, but this is still better than not having anything to trace the function calls with. :)

MyTrace.h

#pragmaonce

#include<stdio.h>

class CMyTrace

{

private:

staticint m_indent;

public:

CMyTrace(LPCTSTR lpszFormat, ...);

virtual ~CMyTrace(void);

};

// If you comment this one line out then the

// debug string part won't be compiled into the project

// E.g. you could do that when compiling the release version

#define USE_CMYTRACE

#ifdef USE_CMYTRACE

#define MYTRACE CMyTrace myTrace

#else

#define MYTRACE

#endif

MyTrace.cpp

#include"StdAfx.h"

#include"MyTrace.h"

int CMyTrace::m_indent = 0;

CMyTrace::CMyTrace(LPCTSTR lpszFormat, ...)

{

TCHAR szBuffer[512];

_stprintf(szBuffer, _T("%*s"), m_indent * 2, _T(""));

::OutputDebugString(szBuffer);

va_list args;

va_start(args, lpszFormat);

int nBuf;

nBuf = _vsntprintf(szBuffer, 511, lpszFormat, args);

::OutputDebugString(szBuffer);

::OutputDebugString(_T("\n"));

va_end(args);

m_indent++;

}

CMyTrace::~CMyTrace(void)

{

m_indent--;

}

You can call the trace function at the beginning of each of your function.

STDMETHODIMP CMyAddInServer::OnActivate (VARIANT_BOOL FirstTime)

{

MYTRACE(_T("(%s, %d) %s"), _T(__FILE__), __LINE__, _T(__FUNCTION__));

// etc...

return S_OK ;

}

The result in the Output Debug window of Visual Studio would look something like this when debugging the program: