2009-04-09 34 views
23

Quiero implementar un rastreador de función, que rastrearía cuánto tiempo tarda una función en ejecutarse. He siguiente clase para el mismo: -¿Hay alguna manera de obtener el nombre de la función dentro de una función de C++?

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. 
    */ 
} 

me gustaría saber si hay alguna manera de obtener el nombre de la función desde el interior de una función? Básicamente quiero que los usuarios de mi clase simplemente creen un objeto igual. No pueden pasar el nombre de la función.

Respuesta

21

VC++ tiene

__FUNCTION__ for undecorated names 

y

__FUNCDNAME__ for decorated names 

y usted puede escribir una macro que sí asignar un objeto y pasar el nombre de macro-yelding dentro del constructor. Smth como

#define ALLOC_LOGGER FuncTracer ____tracer(__FUNCTION__); 
+0

Funciona en VS2003 pero no funciona en VC6 – Canopus

+0

¿Qué no funciona? Las macros no son reconocidas por el compilador o qué? – sharptooth

+0

Sí. En la compilación en VC6 dice __FUNCTION__ como identificador no declarado. ¿Me estoy perdiendo algo o no es compatible? – Canopus

46

C99 tiene __func__, pero para C++ esto será compilador específico. En el lado positivo, algunas de las versiones específicas del compilador proporcionan información de tipo adicional, lo cual es particularmente bueno cuando trazas dentro de una función/clase con plantilla.

  • MSVC: __FUNCTION__, __FUNCDNAME__, __FUNCSIG__
  • GCC: __func__, __FUNCTION__, __PRETTY_FUNCTION__

biblioteca Boost ha definido macro BOOST_CURRENT_FUNCTION para la mayoría de los compiladores de C++ en la cabecera boost/current_function.hpp. Si el compilador es demasiado viejo para admitir esto, el resultado será "(desconocido)".

3

me iba a decir que no sabía de tal cosa, pero luego vi las otras respuestas ...

Puede ser que le interese saber que un perfilador de ejecución (como gprof) hace exactamente lo que usted Preguntar acerca de: rastrea la cantidad de tiempo dedicado a la ejecución de cada función. Un generador de perfiles básicamente funciona registrando el puntero de instrucción (IP), la dirección de la instrucción que se está ejecutando actualmente, cada 10ms o más. Una vez que el programa se haya ejecutado, invocará un postprocesador que examinará la lista de direcciones IP y el programa, y ​​convertirá esas direcciones en nombres de función. Así que sugeriría simplemente usar el puntero de instrucción, en lugar del nombre de la función, porque es más fácil de codificar y porque es más eficiente trabajar con un solo número que con una cadena.

+1

Tenga en cuenta que para hacer esto, también debe guardar las direcciones de carga de la imagen del ejecutable/librerías, de lo contrario, no podrá interpretar las direcciones grabadas de manera significativa. Además, la compatibilidad del compilador para los perfiladores personalizados (por ejemplo _penter/_pexit en MSVC) puede ser una alternativa al muestreo periódico. – bk1e

Cuestiones relacionadas