2009-03-30 23 views
9

Can gcc cracher, donné un fichier C, une liste des tous les appels de fonction qui se produisent, avec nom de fichier et numéro de ligne pour l'appel lui-même et pour la déclaration de la fonction? Je sais que gcc conserve en quelque sorte cette information avec -g (les débogueurs en dépendent) et qu'il peut vider les graphes de flux de contrôle avec -dr (mais sans nom de fichier ni numéro de ligne); mais existe-t-il un outil prêt à l'emploi qui prend la sortie gcc et fait ce que je veux?comment faire gcc cracher un mappage de graphes de flux aux numéros de ligne de code source

La raison pour laquelle je veux un tel outil à utiliser gcc est que cela me permettra de l'utiliser avec le système de construction standard le plus de logiciel basé sur gcc-vient avec (par exemple ./configure & & marque), même dans les cas où les outils que compter sur leur propre préprocesseur et/ou parser sont un souci majeur pour s'intégrer. Je suis déjà au courant de plusieurs de ces outils, par exemple ctags. Donc, cette question est une suite à question 525899.

Répondre

9

Essayez l'option gcc -fdump-tree-fixupcfg-lineno.

Il va "joliment" analyser AST (avec les numéros de ligne) d'une manière qui peut facilement être analysée en utilisant lexer relativement simple ou tout moteur regex. Il suffit de trouver tous les non-mots-clés précédés « = » et suivi de « (» - ce sera les appels de fonction

Toutes les expressions complexes seront divisés en plusieurs lignes donc pas de deux appels de fonction apparaîtront sur une ligne

..

Prenez programme simple:

#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; 
} 

compiler avec -fdump-tree-fixupcfg-lineno et vous obtenez quelque chose comme ceci:

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 

} 

vous ne recevrez pas de complexe expressions - juste des affectations et appel de fonction et pas de macros CPP, très facile à analyser. Les boucles et les conditionnels ne le rendent pas beaucoup plus difficile.

+0

C'est presque exactement ce que j'espérais. Les appels dans un if (0) semblent manquer, et il peut y avoir plus de détails à prendre en compte, mais c'est beaucoup plus loin que tout ce que j'avais trouvé jusqu'ici. Merci beaucoup! – reinierpost

+0

L'option a été supprimée: http://stackoverflow.com/questions/2161567/i-need-a-tree-dump-option-which-doesnt-exist-any-more-in-current-gcc-versions – reinierpost

+0

@ reinierpost Oui, je suis conscient de cela, comme vous pouvez le voir dans mon commentaire à la question que vous avez liée, mais cela a changé après mon post. Cependant, depuis GCC 4.5, vous pouvez utiliser les plugins GCC (comme une fonctionnalité standard) afin que vous puissiez obtenir AST depuis l'interface GCC et le traiter - c'est ainsi que j'ai contourné ce problème. – qrdl

3

Valgrind et KCacheGrind semble un bon outil pour cette utilisation:

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

Cela vous donnera un fichier appelé callgrind.out.pid que vous pouvez ouvrir avec KCacheGrind. Cela vous permettra de voir beaucoup d'informations comme le graphique d'appel, le nom de fichier ...

+0

Merci pour votre suggestion. Cela va me donner un callgraph dynamique, montrant les appels faits pendant que le programme est exécuté, non? J'ai aussi besoin de ça, mais ce n'est pas ce que je demandais. Mais je vais certainement essayer KCacheGrind. – reinierpost

+0

Ce n'est pas aussi proche que je l'espérais. Il n'imprime pas les numéros de ligne avec les déclarations, ni n'imprime les numéros de ligne des appels avec des appels. – reinierpost

3

Vous pouvez essayer Treehydra, un plugin GCC qui vous donne un accès en lecture seule aux représentations internes de code de GCC lors de la compilation. (Cependant, c'est un peu une corvée de construire, et je ne suis pas sûr que cela donnera de meilleurs résultats que -fdump- * pour ce problème.)

+0

Je n'étais pas au courant de TreeHydra et je vais le vérifier la prochaine fois que j'en aurai besoin. Merci! – reinierpost