Frage

Ich bin auf der Suche nach einem schönen Stack Overflow-Stil Antwort auf die erste Frage in der alten Blog-Post C ++ Code Größe , die ich wiederholen unten:

  

ich wie ein Werkzeug wirklich würde (im Idealfall, g ++ basiert), das zeigt mir, welche Teile des kompilierten / verknüpften Code generiert werden, aus welchen Teilen von C ++ Quellcode. Zum Beispiel, um zu sehen, ob eine bestimmte Vorlage für Hunderte von verschiedenen Arten instanziiert wird (fixierbar über eine Template-Spezialisierung) oder ob Code inlined wird übermäßig, oder ob bestimmte Funktionen sind größer als erwartet.

War es hilfreich?

Lösung

Es scheint, wie so etwas wie dies sollte vorhanden sein, aber ich habe nichts mehr wie früher. Ich kann Ihnen sagen, wie ich über scripting diese zusammen gehen würde, wenn. Es gibt wahrscheinlich schneller und / oder sexier Möglichkeiten, es zu tun.

Zuerst einige Sachen, die Sie vielleicht schon wissen:

Der addr2line Befehl nimmt eine Adresse und kann Ihnen sagen, wo der Quellcode, dass der Maschinencode dort implementiert. Die ausführbaren werden muss, um mit dem Debuggen Symbole gebaut, und Sie werden wahrscheinlich wollen nicht, es zu optimieren viel (-O0, -O1 oder -Os ist wahrscheinlich so hoch wie Sie zunächst sowieso gehen wollen würde). addr2line hat mehrere Flaggen, und Sie werden ihre manuelle Seite lesen möchten, aber Sie werden auf jeden Fall C oder --demangle verwenden müssen, wenn Sie C ++ Funktionsnamen das Sinn in der Ausgabe sehen.

Der objdump Befehl alle möglichen interessanten Dinge über die Sachen in vielen Arten von Objektdateien ausdrucken können. Eines der Dinge, die sie tun können, ist eine Tabelle auszudrucken, die die Symbole in oder durch eine Objektdatei bezeichnet (einschließlich ausführbaren Dateien).

Nun, was wollen Sie damit zu tun:

Was Sie wollen ist für objdump Ihnen zu sagen, die Adresse und die Größe des .text Abschnitt. Dies ist, wo tatsächlich ausführbaren Maschinencode lebt. Es gibt mehrere Möglichkeiten, dies zu tun, aber der einfachste (dazu sowieso) ist wahrscheinlich für Sie zu tun:

objdump -h my_exe | grep text

Das in etwas ergeben sollte wie:

 12  .text       0000049  000000f000  0000000f000 00000400  2**4

Wenn Sie es nicht grep es würden Sie eine Überschrift wie:

Idx  Name        Size     VMA         LMA         File off  Algn

ich denke, ausführbare Dateien für die VMA und LMA sollten gleich sein, so wird es keine Rolle, die Sie verwenden, aber ich denke, LMA ist das beste. Sie wollen auch die Größe.

Mit der LMA und Größe können Sie wiederholt addr2line für den Quellcode Ursprung des Maschinencodes fragen nennen. Ich bin mir nicht sicher, wie dies funktionieren würde, wenn Sie eine Adresse übergeben, die innerhalb einer Anweisung war, aber ich denke, es sollte funktionieren.

addr2line -e my_exe <address>

Die Ausgabe von dieser wird ein Pfad / Dateiname, ein Doppelpunkt und eine Zeilennummer sein. Wenn Sie das Auftreten von jeder eindeutigen Pfad / Datei zu zählen sind: num sollten Sie in der Lage sein, bei denen zu suchen, die die höchsten Zählungen haben. Perl Hashes den Pfad / Datei: num als Schlüssel und einen Zähler als Wert wäre eine einfache Möglichkeit, dies zu realisieren, obwohl es schnellere Wege sind, wenn Sie das läuft zu langsam finden. Sie können auch Dinge herausfiltern, dass Sie bestimmen können, müssen nicht früh aufgenommen werden. Für die Ausgabe Anzeigen können Sie verschiedene Linien von der gleichen Funktion, um herauszufiltern, aber Sie können feststellen, dass verschiedene Linien feststellen, innerhalb einer Funktion unterschiedliche Zählungen haben, die interessant sein könnten. Wie auch immer, dass entweder, indem Sie getan werden, um die Funktionsnamen addr2line sagen oder mit objdump -t im ersten Schritt und Arbeit eine Funktion auf einmal.

Wenn Sie sehen, dass einige Template-Code oder andere Codezeilen zeigen häufig in ausführbaren Dateien mehr als Sie denken, sie sollten Sie sie dann leicht finden können und haben einen genaueren Blick. Makros und Inline-Funktionen zeigen kann Ende bis sich unterschiedlich manifestieren, als Sie erwarten.

Wenn Sie nicht wissen, objdump und addr2line ist von dem GNU binutils Paket, die mehrere andere nützliche Tools enthält.

Andere Tipps

Wenn Sie suchen Quellen Code aufblasen in C ++ Code zu finden, habe ich ‚nm‘ dafür verwendet. Mit dem folgenden Befehl wird alle die Symbole in der App mit den größten Code und Datenblöcken auf der Top-Liste:

nm --demangle --print-size --size-sort --reverse-sort <executable_or_lib_name> | less

Ich schrieb vor kurzem ein Tool, aufblasen Vorwürfe , die etwas Ähnliches, was tut < a href = "https://stackoverflow.com/questions/2509734/break-down-c-code-size/2510872#2510872"> nategoose vorgeschlagen .

Ich weiß nicht, ob es hilft, aber es gibt eine gcc Flag den Assembler-Code erzeugt sie in eine Textdatei für die Prüfung zu schreiben.

" ES     Verwendet anstelle von -c der Assembler Quelle zu verursachen Datei erzeugt werden, .s als Erweiterung verwenden, anstelle der Objektdatei. Dies kann nützlich sein, wenn Sie den erzeugten Assembler-Code untersuchen müssen. „

In den meisten C-Compiler gibt es einen Weg, um eine .map-Datei zu erzeugen. In dieser Datei sind alle der kompilierten Bibliotheken ihre Adresse und ihre Größe. Sie können diese Map-Datei zu Hilfe verwenden Sie bestimmen, welche Dateien sollten Sie zunächst zu optimieren suchen.

Ich weiß nicht, wie Code- abzubilden> generierte Assembly im Allgemeinen.

Für Vorlage instantiations Sie so etwas wie "strings -a | grep | sort -u | gc ++ filt" verwenden können. Ein ungefähres Bild davon zu bekommen, was erstellt wird wird

Die beiden anderen Elemente, die Sie erwähnt subjektiv scheinen ziemlich eigentlich. Was ist „zu viel“ inlining? Sind Sie besorgt, Ihre Binärdatei aufgeblasen zu werden? Das einzige, was es zu tun ist, gehen tatsächlich in gdb und zerlegen, um den Anrufer zu sehen, was es erzeugt wird, nichts für „übermäßig“ zu prüfen, im allgemeinen inlining.

Für die Funktionsgröße, wieder ich bin neugierig, warum es wichtig ist? Sind Sie versuchen, Code zu finden, die unerwartet erweitert, wenn kompiliert? Wie definieren Sie selbst, was eine erwartete Größe ist für ein Werkzeug zu untersuchen? Auch hier können Sie immer jede Funktion heucheln, dass Sie weit mehr Code kompiliert vermuten, als Sie wollen, und genau sehen, was der Compiler tut.

In Visual C ++, das ist im Wesentlichen, was PDB-Dateien sind für.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top