105 votes

Générer appelant graphique pour le code C++

Je suis en train de générer de l'appelant graphique avec pour trouver tous les chemins d'exécution possibles sur une fonction en particulier (alors que je n'ai pas à découvrir tous les chemins d'accès manuellement, comme il y a beaucoup de chemins qui mènent à cette fonction). Par exemple:

path 1: A -> B -> C -> D  
path 2: A -> B -> X -> Y -> D  
path 3: A -> G -> M -> N -> O -> P -> S -> D  
...  
path n: ...

J'ai essayé Codeviz et Doxygen, en quelque sorte, les deux résultats ne montrent rien mais callees de la fonction cible, D. Dans mon cas, D est une fonction membre d'une classe dont l'objet sera enveloppé dans un pointeur intelligent. Les Clients seront toujours obtenir le pointeur intelligent objet dans une usine afin d'invoquer D.

Quelqu'un sait-il comment faire?

Merci,
shiouming

141voto

static void D() { }
static void Y() { D(); }
static void X() { Y(); }
static void C() { D(); X(); }
static void B() { C(); }
static void S() { D(); }
static void P() { S(); }
static void O() { P(); }
static void N() { O(); }
static void M() { N(); }
static void G() { M(); }
static void A() { B(); G(); }

int main() {
  A();
}

Alors

$ clang++ -S -emit-llvm main1.cpp -o - | opt -analyze -dot-callgraph
$ dot -Tpng -ocallgraph.png callgraph.dot

Les rendements de certaines brillant de l'image (il y a un "nœud externe", car main a une liaison externe et pourrait être appelé de l'extérieur que de l'unité de traduction trop):

Callgraph

Vous souhaitez peut-être post-traiter cela avec c++filt, de sorte que vous pouvez obtenir le unmangled les noms des fonctions et des classes concernées. Comme dans l'

#include <vector>

struct A { 
  A(int);
  void f(); // not defined, prevents inlining it!
};

int main() {
  std::vector<A> v;
  v.push_back(42);
  v[0].f();
}

$ clang++ -S -emit-llvm main1.cpp -o - |
   opt -analyze -std-link-opts -dot-callgraph
$ cat callgraph.dot | 
   c++filt | 
   sed 's,>,\\>,g; s,-\\>,->,g; s,<,\\<,g' | 
   gawk '/external node/{id=$1} $1 != id' | 
   dot -Tpng -ocallgraph.png    

Les rendements de cette beauté (oh mon dieu, la taille sans les optimisations activée, c'était trop gros!)

Beauty

Mystique sans nom de la fonction, Node0x884c4e0, est un espace réservé supposé être appelé par une fonction dont la définition n'est pas connue.

12voto

Ira Baxter Points 48153

De manière statique d'un calcul précis C++ graphe d'appel est dur, parce que vous avez besoin d'un précis de la langue de l'analyseur, corriger la recherche d'un nom, et un de bons points à l'analyseur qui fait honneur à la langue de la sémantique correctement. Doxygen ne pas avoir l'un de ces, je ne sais pas pourquoi les gens prétendent comme pour C++, il est facile de construire un 10 ligne C++ exemple que Doxygen, à tort, analyse).

Vous pourriez être mieux de l'exécution d'un calendrier profiler, qui recueille un graphe d'appel dynamiquement (c'est ce qui décrit le nôtre) et simplement l'exercice d'un grand nombre de cas. Ces profileurs va vous montrer la réelle graphe d'appel exercé.

EDIT: je me suis soudain souvenu de Comprendre pour le C++, qui prétend construire les graphes d'appels. Je ne sais pas ce qu'ils utilisent pour un analyseur, ou s'ils ne l'analyse détaillée de droite; je n'ai pas d'expérience particulière avec leur produit.

Je suis impressionné par Schaub, en réponse, à l'aide de Clang; je m'attends à ce Clang pour avoir tous les éléments à droite.

3voto

mabalenk Points 25

Pour que l' clang++ de commande pour trouver les fichiers d'en-tête standard comme mpi.h deux options supplémentaires devraient être utilisés -### -fsyntax-only, c'est à dire l'intégralité de la commande devrait ressembler à:

clang++ -### -fsyntax-only -S -emit-llvm main1.cpp -o - | opt -analyze -dot-callgraph

1voto

Resonantium Points 1

Le "C++ Bsc Analyzer" peut afficher des graphiques d'appel - par la lecture du fichier généré par le bscmake utilitaire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X