Track program workflow in C++

<?xml encoding=”UTF-8″>By Adam Nagy

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

#pragma once

 

#include <stdio.h>

 

class CMyTrace

{

private:

  static int 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:

(MyAddInServer.cpp, 34) CMyAddInServer::OnActivate
(MyCommands.cpp, 9) CMyCommands::CMyCommands
(MyCommandBase.cpp, 15) CMyCommandBase::CreateButtonDefinitionHandler
(InteractionEventsBase.cpp, 13) CInteractionEventsBase::CInteractionEventsBase
(MyCommands.cpp, 41) CMyCommands::CreateMenu
(MyUtilities.cpp, 78) CMyUtilities::CreateCommandCategory
(MyUtilities.cpp, 9) CMyUtilities::AddButtonToCommandCategory
(MyCommandBase.cpp, 107) CMyCommandBase::GetButtonDefinition
(MyCommands.cpp, 91) CMyCommands::CreateAssemblyRibbonTab
(MyUtilities.cpp, 115) CMyUtilities::GetRibbon
(MyUtilities.cpp, 143) CMyUtilities::CreateRibbonTab
(MyUtilities.cpp, 461) CMyUtilities::AddRibbonTabToEnvironment
(MyUtilities.cpp, 606) CMyUtilities::GetEnvironment
(MyUtilities.cpp, 191) CMyUtilities::CreateRibbonPanel
(MyUtilities.cpp, 238) CMyUtilities::AddButtonToRibbonPanel
(MyCommandBase.cpp, 107) CMyCommandBase::GetButtonDefinition
(MyUtilities.cpp, 361) CMyUtilities::FindCommandControl

Comments

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading