Tools zum Abrufen eines bildlichen Funktionsaufrufdiagramms des Codes [closed]
Lesezeit: 6 Minuten
goldene Mitte
Ich habe einen großen Arbeitsbereich mit vielen Quelldateien von C-Code. Obwohl ich die von einer Funktion aufgerufenen Funktionen in MS VS2005 mit dem Objektbrowser und auch in MSVC 6.0 sehen kann, zeigt dies nur Funktionen, die von einer bestimmten Funktion in einer nicht grafischen Art der Anzeige aufgerufen werden. Außerdem zeigt es nicht die Funktion, die ab sagen aufgerufen wird main()und dann die Funktionen, die von ihr aufgerufen werden, und so weiter, tiefer in die Funktion auf Blattebene.
Ich brauche ein Tool, das mir bildlich einen Funktionsaufrufgraph mit Funktionen gibt callee und caller verbunden durch Pfeile oder ähnliches, ausgehend von main() bis zur letzten Funktionsebene, oder zumindest einen Aufrufgraphen aller Funktionen in einer C-Quelldatei bildlich darstellen. Es wäre toll, wenn ich diese Grafik ausdrucken könnte.
Irgendwelche guten Tools dafür (müssen keine kostenlosen Tools sein)?
Frage zu CodeViz, wenn Sie Ihren Code an diesen übergeben, wird der Code generiert oder nicht? Oder sollten Sie selbst einen Graphen mit Codevis erstellen?
– Mohammad Reza Rezwani
5. April 2014 um 7:39 Uhr
Ich habe es gerade mit Ägypten versucht. Es ist grafisch schrecklich. Bei den anderen bin ich mir nicht sicher.
– ar2015
28. Mai 2016 um 9:15 Uhr
Ciro Santilli OurBigBook.com
Dynamische Analysemethoden
Hier beschreibe ich einige dynamische Analysemethoden.
Dynamische Methoden führen das Programm tatsächlich aus, um den Anrufgraphen zu bestimmen.
Das Gegenteil von dynamischen Methoden sind statische Methoden, die versuchen, es allein aus der Quelle zu ermitteln, ohne das Programm auszuführen.
Vorteile dynamischer Methoden:
fängt Funktionszeiger und virtuelle C++-Aufrufe ab. Diese sind in großer Zahl in jeder nicht-trivialen Software vorhanden.
Nachteile dynamischer Methoden:
Sie müssen das Programm ausführen, was möglicherweise langsam ist, oder benötigen ein Setup, das Sie nicht haben, z. B. Cross-Compilation
Es werden nur Funktionen angezeigt, die tatsächlich aufgerufen wurden. Beispielsweise könnten einige Funktionen abhängig von den Befehlszeilenargumenten aufgerufen werden oder nicht.
int f2(int i) { return i + 2; }
int f1(int i) { return f2(2) + i + 1; }
int f0(int i) { return f1(1) + f2(2); }
int pointed(int i) { return i; }
int not_called(int i) { return 0; }
int main(int argc, char **argv) {
int (*f)(int);
f0(1);
f1(1);
f = pointed;
if (argc == 1)
f(1);
if (argc == 2)
not_called(1);
return 0;
}
Verwendungszweck:
sudo apt-get install -y kcachegrind valgrind
# Compile the program as usual, no special flags.
gcc -ggdb3 -O0 -o main -std=c99 main.c
# Generate a callgrind.out.<PID> file.
valgrind --tool=callgrind ./main
# Open a GUI tool to visualize callgrind data.
kcachegrind callgrind.out.1234
Sie befinden sich jetzt in einem großartigen GUI-Programm, das viele interessante Leistungsdaten enthält.
Wählen Sie unten rechts den Reiter „Anrufgrafik“ aus. Dies zeigt ein interaktives Anrufdiagramm, das mit Leistungsmetriken in anderen Fenstern korreliert, wenn Sie auf die Funktionen klicken.
Um das Diagramm zu exportieren, klicken Sie mit der rechten Maustaste darauf und wählen Sie „Diagramm exportieren“. Das exportierte PNG sieht so aus:
Daran können wir erkennen:
der Wurzelknoten ist _startdas ist der eigentliche ELF-Einstiegspunkt, und enthält eine Boilerplate für die glibc-Initialisierung
f0, f1 und f2 werden wie erwartet voneinander aufgerufen
pointed wird ebenfalls angezeigt, obwohl wir es mit einem Funktionszeiger aufgerufen haben. Es wäre möglicherweise nicht aufgerufen worden, wenn wir ein Befehlszeilenargument übergeben hätten.
not_called wird nicht angezeigt, weil es im Lauf nicht aufgerufen wurde, weil wir kein zusätzliches Befehlszeilenargument übergeben haben.
Das Coole daran valgrind ist, dass es keine speziellen Kompilierungsoptionen erfordert.
Daher können Sie es auch verwenden, wenn Sie nicht über den Quellcode verfügen, sondern nur über die ausführbare Datei.
valgrind schafft dies, indem es Ihren Code durch eine leichtgewichtige “virtuelle Maschine” laufen lässt. Dadurch wird die Ausführung im Vergleich zur nativen Ausführung auch extrem langsam.
Wie in der Grafik zu sehen ist, werden auch Timing-Informationen zu jedem Funktionsaufruf abgerufen, und diese können verwendet werden, um das Programm zu profilieren, was wahrscheinlich der ursprüngliche Anwendungsfall dieses Setups ist, und nicht nur, um Aufrufgrafiken anzuzeigen: How can I profile C++-Code, der unter Linux ausgeführt wird?
Wahrscheinlich die effizienteste Methode neben spezifischer Hardware-Tracing-Unterstützung, hat aber den Nachteil, dass Sie den Code neu kompilieren müssen.
Beachten Sie nur, dass der dynamische Aufrufgraph nur einen Lauf des Programms abdeckt.
– smWikipedia
30. September 2018 um 7:41 Uhr
@smwikipedia ja, ich habe die Antwort aktualisiert, um das klarer zu machen
– Ciro Santilli OurBigBook.com
30. September 2018 um 14:19 Uhr
Auch hier erklärt – stackoverflow.com/questions/311840/…
– tauseef_CuriousGuy
18. März 2019 um 10:29 Uhr
Verstehe leistet sehr gute Arbeit beim Erstellen von Anrufdiagrammen.
Für Leute, die dies über Google finden, funktioniert diese Toolchain auch für andere Sprachen, einschließlich Verarbeitung und Java, obwohl sie die Objektinitialisierung von Java nicht zu mögen scheint und new nicht als einen Funktionsaufruf enthaltend erkennt.
– John Harlan
10. März um 18:07 Uhr
Jason Nyberg
Sie können sich meinen Bash-basierten C-Call-Tree-Generator ansehen hier. Sie können eine oder mehrere C-Funktionen angeben, für die Sie Informationen zum Aufrufer und/oder zum Angerufenen wünschen, oder Sie können eine Reihe von Funktionen angeben und den Erreichbarkeitsgraphen von Funktionsaufrufen bestimmen, der sie verbindet … D. h., sagen Sie mir alle Wege main( ), foo() und bar() verbunden sind. Es verwendet graphviz/dot für eine Grafik-Engine.
Wie man diese Kombination verwendet, um den Graphen zu erhalten, gibt es ein Tutorial oder zumindest eine Erklärung.
Für Leute, die dies über Google finden, funktioniert diese Toolchain auch für andere Sprachen, einschließlich Verarbeitung und Java, obwohl sie die Objektinitialisierung von Java nicht zu mögen scheint und new nicht als einen Funktionsaufruf enthaltend erkennt.
– John Harlan
10. März um 18:07 Uhr
Astrée ist meiner Meinung nach das robusteste und ausgeklügeltste Tool, das es gibt.
14221500cookie-checkTools zum Abrufen eines bildlichen Funktionsaufrufdiagramms des Codes [closed]yes
Siehe auch: stackoverflow.com/a/17844310/1959808
– 0 _
3. Mai 2015 um 19:39 Uhr
en.wikipedia.org/wiki/Call_graph#Software
– 象嘉道
1. Dezember 2020 um 16:18 Uhr