2009-04-09 13 views
23

Voglio implementare un tracciante di funzione, che dovrebbe tracciare quanto tempo una funzione sta prendendo per eseguire. Ho seguito classe per il medesimo: -C'è un modo per ottenere il nome della funzione all'interno di una funzione 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. 
    */ 
} 

Voglio sapere se c'è qualche modo per ottenere il nome della funzione all'interno di una funzione? Fondamentalmente voglio che gli utenti della mia classe semplicemente creino un oggetto allo stesso modo. Non possono passare il nome della funzione.

risposta

21

VC++ ha

__FUNCTION__ for undecorated names 

e

__FUNCDNAME__ for decorated names 

e si può scrivere una macro che si allocare un oggetto e passare il nome di macro-cedimento all'interno del costruttore. Smth come

#define ALLOC_LOGGER FuncTracer ____tracer(__FUNCTION__); 
+0

Funziona in VS2003 ma non funziona in VC6 – Canopus

+0

Che cosa non funziona? Le macro non sono riconosciute dal compilatore o cosa? – sharptooth

+0

Sì. Nella compilazione in VC6, dice __FUNCTION__ come identificatore non dichiarato. Mi manca qualcosa o non è supportato? – Canopus

46

C99 ha __func__, ma per C++ questo sarà specifica del compilatore. Sul lato positivo, alcune delle versioni specifiche del compilatore forniscono ulteriori informazioni sul tipo, che è particolarmente utile quando si esegue il tracciamento all'interno di una funzione/classe temporizzata.

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

libreria Boost è definito macro BOOST_CURRENT_FUNCTION per la maggior parte compilatori C++ nell'intestazione boost/current_function.hpp. Se il compilatore è troppo vecchio per supportarlo, il risultato sarà "(sconosciuto)".

3

Stavo per dire che non sapevo di qualsiasi cosa, ma poi ho visto le altre risposte ...

Potrebbe interessarvi sapere che un'esecuzione profiler (come gprof) fa esattamente quello che Stai chiedendo informazioni - tiene traccia della quantità di tempo trascorso nell'esecuzione di ogni funzione. Un profiler funziona fondamentalmente registrando il puntatore dell'istruzione (IP), l'indirizzo dell'istruzione attualmente in esecuzione, ogni 10 ms circa. Al termine dell'esecuzione del programma, si invoca un postprocessore che esamina l'elenco di IP e del programma e converte tali indirizzi in nomi di funzioni. Quindi suggerisco di usare solo il puntatore dell'istruzione, piuttosto che il nome della funzione, sia perché è più semplice da codificare, sia perché è più efficiente lavorare con un singolo numero che con una stringa.

+1

Nota che per fare ciò, devi anche salvare gli indirizzi di caricamento dell'immagine dell'eseguibile/librerie, altrimenti potresti non essere in grado di interpretare gli indirizzi registrati in maniera significativa. Inoltre, il supporto del compilatore per i profiler personalizzati (ad es. _penter/_pexit in MSVC) può essere un'alternativa al campionamento periodico. – bk1e