Tools zum Abrufen eines bildlichen Funktionsaufrufdiagramms des Codes [closed]

Lesezeit: 6 Minuten

Benutzeravatar von goldenmean
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)?

Benutzeravatar von Philant
Philant

  • 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 Benutzeravatar von OurBigBook.com
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.

KcacheGrind

https://kcachegrind.github.io/html/Home.html

Testprogramm:

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:

s7dYK

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?

Getestet auf Ubuntu 18.04.

gcc -finstrument-functions + Ausgang

https://github.com/elcritch/etrace

-finstrument-functions fügt Rückrufe hinzu, etrace analysiert die ELF-Datei und implementiert alle Rückrufe.

Ich konnte es aber leider nicht zum Laufen bringen: Warum funktioniert `-finstrument-functions` bei mir nicht?

Die beanspruchte Ausgabe hat folgendes Format:

\-- main
|   \-- Crumble_make_apple_crumble
|   |   \-- Crumble_buy_stuff
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   |   \-- Crumble_buy
|   |   \-- Crumble_prepare_apples
|   |   |   \-- Crumble_skin_and_dice
|   |   \-- Crumble_mix
|   |   \-- Crumble_finalize
|   |   |   \-- Crumble_put
|   |   |   \-- Crumble_put
|   |   \-- Crumble_cook
|   |   |   \-- Crumble_put
|   |   |   \-- Crumble_bake

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.

Benutzeravatar von Ira Baxter
Ira Baxter

Unser DMS-Software-Reengineering-Toolkit hat Statische Kontroll-/Datenfluss-/Points-to-/Call-Graph-Analyse das auf riesige Systeme (~~25 Millionen Zeilen) von C-Code angewendet wurde und solche Anrufgraphen erzeugte, einschließlich Funktionen, die über Funktionszeiger aufgerufen werden.

Sie können CScope + versuchen tseebaum + Graphviz.

  • Wie man diese Kombination verwendet, um den Graphen zu erhalten, gibt es ein Tutorial oder zumindest eine Erklärung.

    – Muhammad Yusuf

    31. Dezember 2018 um 10:28 Uhr

  • @Muhammad Yusuf ja, es gibt einen Wiki-Seite.

    – BillyJoe

    2. Januar 2019 um 14:16 Uhr


  • 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

Benutzeravatar von Jason Nyberg
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.

    – Muhammad Yusuf

    31. Dezember 2018 um 10:28 Uhr

  • @Muhammad Yusuf ja, es gibt einen Wiki-Seite.

    – BillyJoe

    2. Januar 2019 um 14:16 Uhr


  • 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.

1422150cookie-checkTools zum Abrufen eines bildlichen Funktionsaufrufdiagramms des Codes [closed]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy