2009-03-30 9 views
9

Può gcc sputare, dato un file C, un elenco di tutte le chiamate di funzione che si verificano, con nome file e numero di riga sia per la chiamata stessa sia per la dichiarazione della funzione?come rendere gcc sputare una mappatura dai grafici di flusso ai numeri di riga del codice sorgente

So che gcc in qualche modo conserva queste informazioni con -g (i debugger si basano su di esso) e che può scaricare i diagrammi di flusso di controllo con -dr (ma senza nomi di file o numeri di riga); ma c'è uno strumento pronto all'uso che prende l'output di gcc e fa ciò che voglio?

Il motivo che voglio un tale strumento da usare gcc è che questo mi permetterà di usarlo con il sistema di generazione di serie maggior parte dei software gcc-base viene fornito con (ad esempio ./configure & & make), anche nei casi in cui gli strumenti che fare affidamento sul proprio preprocessore e/o parser è una grande seccatura per adattarsi. Sono già a conoscenza di molti di questi strumenti, ad es. ctags. Quindi questa domanda è un seguito a question 525899.

risposta

9

Prova opzione gcc -fdump-tree-fixupcfg-lineno.

Scriverà "pretty print" analizzando AST (con numeri di riga) in un modo che può essere facilmente analizzato utilizzando lessico relativamente semplice o qualsiasi motore regex. Basta trovare tutti i non-parole chiave precedute da '=' e seguito da '(' - sarà chiamate di funzione

Tutte le espressioni complesse saranno divisi in diverse linee in modo appariranno non ci sono due chiamate di funzione su una sola riga

..

prendere semplice programma:

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

#define PI (3.1415926536) 

int main(int argc, char *argv[]) { 
    double angle = PI/2.0; 
    printf("Sine = %lf, cosine = %lf\n", sin(angle), cos(angle)); 
    return EXIT_SUCCESS; 
} 

Compilatelo con -fdump-tree-fixupcfg-lineno e si ottiene qualcosa di simile:

main (argc, argv) 
{ 
    double angle; 
    int D.3381; 
    double D.3380; 
    double D.3379; 

    # BLOCK 2, starting at line 8 
    # PRED: ENTRY (fallthru) 
    [test.c : 8] angle = 1.57079632680000003119857865385711193084716796875e+0; 
    [test.c : 9] D.3379 = [test.c : 9] cos (angle); 
    [test.c : 9] D.3380 = [test.c : 9] sin (angle); 
    [test.c : 9] printf (&"Sine = %lf, cosine = %lf\n"[0], D.3380, D.3379); 
    [test.c : 10] D.3381 = 0; 
    return D.3381; 
    # SUCC: EXIT 

} 

non si ottiene alcun complesso espressioni: solo assegnazioni e chiamate di funzione e nessuna macro CPP, molto facile da analizzare. Loops e condizionali non lo rendono molto più difficile.

+0

Questo è quasi esattamente quello che speravo. Le chiamate all'interno di un if (0) sembrano mancare, e potrebbero esserci altri dettagli da prendere in considerazione, ma è molto più lontano di qualsiasi altra cosa abbia trovato finora. Molte grazie! – reinierpost

+0

L'opzione è stata rimossa: http://stackoverflow.com/questions/2161567/i-need-a-tree-dump-option-which-doesnt-exist-any-more-in-current-gcc-versions – reinierpost

+0

@ reinierpost Sì, ne sono a conoscenza, come puoi vedere nel mio commento alla domanda che hai collegato, ma è cambiato dopo il mio post. Tuttavia, dal momento che GCC 4.5 è possibile utilizzare i plugin GCC (come funzionalità standard) in modo da poter ottenere AST dal front-end di GCC e processarlo, questo è il modo in cui ho risolto questo problema. – qrdl

3

Valgrind e KCachegrind sembra un buon strumento per questo uso:

valgrind --tool=callgrind --dump-instr=yes ./your_binary 

Questo vi darà un file chiamato callgrind.out.pid che è possibile aprire con KCachegrind. Questo ti permetterà di vedere molte informazioni come call graph, nome file ...

+0

Grazie per il tuo suggerimento. Questo mi darà un callgraph dinamico, mostrando le chiamate che vengono fatte mentre il programma viene eseguito, giusto? Ne ho bisogno anche io, ma non è quello che stavo chiedendo. Ma proverò sicuramente KCacheGrind. – reinierpost

+0

Non è così vicino come speravo. Non stampa i numeri di riga con le dichiarazioni, né stampa i numeri delle linee di chiamata con le chiamate. – reinierpost

3

Si potrebbe provare Treehydra, un plug-in GCC che fornisce accesso in sola lettura alle rappresentazioni interne del codice GCC durante la compilazione. (Tuttavia, è un po 'complicato da costruire, e non sono sicuro che fornirà risultati migliori di -fdump- * per questo problema.)

+0

Non ero a conoscenza di TreeHydra e controllerò la prossima volta che ne avrò bisogno. Grazie! – reinierpost

Problemi correlati