2012-11-29 12 views
9

gperftools documentation dice che libprofiler dovrebbe essere collegato in un programma di destinazione:Come viene avviato esattamente il profiler CPU gperftools?

$ gcc myprogram.c -lprofiler 

(senza modificare il codice del programma).

E poi programma deve essere eseguito con una specifica variabile d'ambiente:

CPUPROFILE=/tmp/profiler_output ./a.out 

La domanda è: come si fa libprofile hanno la possibilità di iniziare e finire un profiler quando viene semplicemente caricato, ma le sue funzioni non sono chiamati?

Non esiste alcuna funzione di costruttore in tale libreria (proof). All occasions of "CPUPROFILE" nel codice della libreria non si riferiscono a nessun luogo in cui viene avviato profiler.

Sono fuori di idee, dove cercare dopo?

risposta

8

Come per la documentazione, la pagina Web collegata, sotto Collegamento alla libreria, descrive che il passo -lprofiler è lo stesso del collegamento al file oggetto condiviso con l'opzione LD_PRELOAD.

Il file oggetto condiviso non è uguale al solo file di intestazione. Il file di intestazione contiene dichiarazioni di funzioni che vengono ricercate durante la compilazione di un programma, quindi i nomi delle funzioni vengono risolti, ma i nomi sono solo nomi, non implementazioni. Il file oggetto condiviso (.so) contiene le implementazioni delle funzioni. Per ulteriori informazioni, vedere the following StackOverflow answer.

Source file of /trunk/src/profiler.cc sulla riga 182, ha un costruttore CPUProfiler, che verifica se il profilo deve essere abilitato o meno in base alla variabile di ambiente CPUPROFILE (Riga 187 e Riga 230).

Si chiama quindi la funzione Start sulla linea 237. Come per i commenti in questo file, il distruttore chiama la funzione di stop sulla linea 273.

Per rispondere alla tua domanda credo Linea 132 CpuProfiler CpuProfiler::instance_; è la linea dove la CpuProfiler è istanziato.

Questa mancanza di chiarezza nella documentazione di gperftools è nota, vedere here.

+0

Hi Appleman1234, grazie per la tua risposta. Sì, i numeri di linea che hai indicato hanno qualcosa a che fare con la variabile d'ambiente CPUPROFILE. Ma controllano _absence_ di quella variabile env, non una presenza. Significa che CpuProfiler è già istanziato da qualche parte a seconda del linkage di profiler.quindi linkage (e poi il costruttore controlla se la variabile presenta ecc.). E non c'è ancora un posto simile! Le librerie possono reagire al caricamento, ma questo non avviene (ho inserito un prof al post OP). Qualche idea su dove (e come/perché) CpuProfile viene istanziata automaticamente solo a causa di un collegamento? –

+0

Oh giusto! Questo è esattamente il posto. Grazie per l'edizione, finalmente è tutto chiaro. Molte molte grazie. –

0

Penso che il profiler venga inizializzato con la macro REGISTER_MODULE_INITIALIZER nella parte inferiore di profile-handler.cc (così come in heap-checker.cc, heap-profiler.cc, ecc.). Questo chiama src/base/googleinit.h che definisce un oggetto statico fittizio il cui costruttore viene chiamato quando viene caricata la libreria. Quel costruttore fittizio chiama quindi ProfileHandlerRegisterThread() che quindi usa la variabile pthread_once per inizializzare l'oggetto singleton (ProfileHandler :: instance_).

La funzione REGISTER_MODULE_INITIALIZER simula le funzioni module_init()/module_exit() visualizzate nei moduli del kernel caricabili di Linux.

(la mia risposta si basa sulla versione 2.0 del gperftools)