views:

2701

answers:

3

I want to implement a function tracer, which would trace how much time a function is taking to execute. I have following class for the same:-

class FuncTracer
{
    public:
     FuncTracer(LPCTSTR strFuncName_in)
     {
      m_strFuncName[0] = _T('\0');
      if( strFuncName_in ||
       _T('\0') != strFuncName_in[0])
      { 
       _tcscpy(m_strFuncName,strFuncName_in);

       TCHAR strLog[MAX_PATH];
       _stprintf(strLog,_T("Entering Func:- <%s>"),m_strFuncName);
       LOG(strLog)

       m_dwEnterTime = GetTickCount();
      }
     }

     ~FuncTracer()
     {
      TCHAR strLog[MAX_PATH];
      _stprintf(strLog,_T("Leaving Func:- <%s>, Time inside the func <%d> ms"),m_strFuncName, GetTickCount()-m_dwEnterTime);
      LOG(strLog)
     }

    private:
     TCHAR m_strFuncName[MAX_PATH];
     DWORD m_dwEnterTime;
};

void TestClass::TestFunction()
{
    // I want to avoid writing the function name maually..
    // Is there any macro (__LINE__)or some other way to 
    // get the function name inside a function ??

    FuncTracer(_T("TestClass::TestFunction"));
    /*
     * Rest of the function code.
     */
}

I want to know if there is any way to get the name of the function from inside of a function? Basically I want the users of my class to simply create an object the same. They may not pass the function name.

+9  A: 

VC++ has

__FUNCTION__ for undecorated names

and

__FUNCDNAME__ for decorated names

And you can write a macro that will itself allocate an object and pass the name-yelding macro inside the constructor. Smth like

#define ALLOC_LOGGER FuncTracer ____tracer( __FUNCTION__ );
sharptooth
Its working in VS2003 but doesnt work in VC6
Canopus
What's not working? The macros are not recognized by the compiler or what?
sharptooth
Yes. On compilation in VC6 it says __FUNCTION__ as undeclared identifier. Am I missing something or is it not supported?
Canopus
Looks like it's not supported by VC6 - http://www.codeguru.com/forum/showthread.php?threadid=385694That's unlucky but you should check VC6 manual - maybe there's some other similar macro.
sharptooth
+1, handy! (But compiler-specific.)
j_random_hacker
I think bk1e's answer is more generic.
Matt H
+12  A: 

C99 has __func__, but for C++ this will be compiler specific. On the plus side, some of the compiler-specific versions provide additional type information, which is particularly nice when you're tracing inside a templatized function/class.

  • MSVC: __FUNCTION__, __FUNCDNAME__, __FUNCSIG__
  • GCC: __func__, __FUNCTION__, __PRETTY_FUNCTION__
bk1e
+3  A: 

I was going to say I didn't know of any such thing but then I saw the other answers...

It might interest you to know that an execution profiler (like gprof) does exactly what you're asking about - it tracks the amount of time spent executing each function. A profiler basically works by recording the instruction pointer (IP), the address of the currently executing instruction, every 10ms or so. After the program is done running, you invoke a postprocessor that examines the list of IPs and the program, and converts those addresses into function names. So I'd suggest just using the instruction pointer, rather than the function name, both because it's easier to code and because it's more efficient to work with a single number than with a string.

David Zaslavsky
Note that to do this, you also have to save the image load addresses of the executable/libraries, or else you may not be able to interpret the recorded addresses meaningfully. Also, compiler support for custom profilers (e.g. _penter/_pexit in MSVC) can be an alternative to periodic sampling.
bk1e