2015-12-11 22 views
6

Ich wollte eine Aufnahme machen, um einige Programme zu profilieren, nachdem ich this von CppCon 2015 sprechen gesehen habe. Ich habe die gleiche Google Benchmark-Bibliothek heruntergeladen, die der Typ in der Diskussion verwendet, mein Programm mit den entsprechenden Switches kompiliert , verknüpfte es mit ihm und verwendete dann perf, um einen Lauf aufzuzeichnen. Der Bericht Option gibt mir dies:Perf zeigt verfälschte Funktionsnamen

enter image description here

Wie Sie die Funktionsnamen sehen können, sind nicht sehr gut lesbar. Ich nehme an, dass dies mit C++ - Namensfehlern zu tun hat. Interessanterweise erscheinen alle Funktionsnamen im Video für den Typ, der das Gespräch gehalten hat, aber nicht für mich. Ich glaube nicht, dass die Symbolinformationen vollständig fehlen, weil ich in diesem Fall nur Speicheradressen sehen würde. Aus irgendeinem Grund kann perf den C++ - Namen, der für mich fehlt, nicht "rückgängig machen", und das ist frustrierend anzusehen.

Ich bin mit gcc (g ++) Version 5.2.1, perf ist Version 4.2.6, und ich verwende diese Schalter beim Kompilieren:

-I<my own include path> -L<path to the benchmark library> -O3 -std=c++14 -gdwarf-2 -fno-rtti -Wall -pedantic -lbenchmark -pthread

Der Grund, warum ich nicht -fno-omit-frame-pointer verwenden ist, dass ich stattdessen die Option -gdwarf-2 verwende, die Debugging-Informationen in der ausführbaren zwerg-Datei zurücklässt, die eine Alternative ist, den Frame-Zeiger in diesem Fall an Ort und Stelle zu lassen. Dies bedeutet auch, dass ich --call-graph "dwarf" an perf record übergebe. Wie auch immer, ich habe auch die Frame-Pointer-Methode ausprobiert, und es gibt die gleichen Ergebnisse, also spielt das keine Rolle.

Warum also "perfom" nicht den C++ - Namen Mangling in diesem Fall? Hat das etwas mit der Verwendung von GCC zu tun, was natürlich bedeutet, dass ich libstdC++ benutze?

+1

Ich benutze Arch Linux und 'Perf-Bericht' zeigt korrekte Symbol-Demandging. Die man-Seite für perf zeigt auch an, dass die Option '--demangle' aktiviert ist, die standardmäßig aktiviert ist. Da ich nicht das gleiche Verhalten wie Sie sehe, habe ich keine Antwort, aber was Sie sehen, ist nicht Standardverhalten erwartet. –

+0

Ich habe versucht, diesen Schalter auch manuell hinzufügen, aber es hat nichts geändert – adam10603

+0

@GabrielSouthern Verwenden Sie auch gcc? – adam10603

Antwort

1

Wenn perf report gibt Ihnen verstümmelten Namen wie _Z*, _ZN*, _ZL* etc, bedeutet dies, dass Ihr perf Werkzeug ohne Zugriff auf Demangling Funktion kompiliert wurde oder damit deaktiviert. Es gibt Code demangler in Makefiles zu ermitteln:

http://elixir.free-electrons.com/linux/v4.2.6/source/tools/perf/Makefile.perf

# Define NO_DEMANGLE if you do not want C++ symbol demangling. 
# Define NO_LIBELF if you do not want libelf dependency (e.g. cross-builds) 

http://elixir.free-electrons.com/linux/v4.2.6/source/tools/perf/config/Makefile

ifdef NO_LIBELF 
... 
    NO_DEMANGLE := 1 
... 
else 
    ifeq ($(feature-libelf), 0) 
    ifeq ($(feature-glibc), 1) 
     LIBC_SUPPORT := 1 
    endif 
    ... 
    ifeq ($(LIBC_SUPPORT),1) 
     ... 
     NO_DEMANGLE := 1 
    ... 

Tests sind im tools/build/feature Verzeichnis: http://elixir.free-electrons.com/linux/v4.2.6/source/tools/build/feature und libelf Funktion aktiviert ist, wenn Testprogramm mit elf_begin Funktion von libelf (<libelf.h> header of elfutils package, -lelf Verknüpfung) ist verfügbar (und gibt etwas zurück? Gibt es Lauftest? Was ist mit Cross-over? erstellt, wenn Kernel-Generator-Maschine kann nicht direkt mit ./test-libelf.bin Zielcomputer Elf-Binärdateien ausführen und muss ssh zu realen Maschine oder einige Benutzer/System qemu?).

und der Code in perf Implementierung zu tun Demangling (mit cplus_demangle wenn HAVE_CPLUS_DEMANGLE_SUPPORT definiert, ohne Verwendung eines demangle ist NO_DEMANGLE nach Makefiles eingestellt, mit bfd.h und bfd_demangle Funktion docs - 2.3.1.24 bfd_demangle): http://elixir.free-electrons.com/linux/v4.2.6/source/tools/perf/util/symbol-elf.c#L19

#ifdef HAVE_CPLUS_DEMANGLE_SUPPORT 
extern char *cplus_demangle(const char *, int); 

static inline char *bfd_demangle(void __maybe_unused *v, const char *c, int i) 
{ 
    return cplus_demangle(c, i); 
} 
#else 
#ifdef NO_DEMANGLE 
static inline char *bfd_demangle(void __maybe_unused *v, 
       const char __maybe_unused *c, 
       int __maybe_unused i) 
{ 
    return NULL; 
} 
#else 
#define PACKAGE 'perf' 
#include <bfd.h> 
#endif 

Diese alles ist etwas seltsam (noch keine Standard-C++ - Entangle-Funktion in der Linux-Welt in der Post C++ 11 Epoche?). Und Ihre Perf wurde falsch oder falsch konfiguriert - es ist der Grund, warum es Namen nicht abwandelt.billyw linked answer von Michal Fapso, dass dies Bug 1396654 von Ubuntu - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 ist.

Sie können mit c++filt Programm Hack des Filtern Ausgabe von perf zu tun, aber es verhindert, dass Sie mit interaktivem Standard TUI Schnittstelle von perf (add less oder Schreiben von Dateien in Text sehr lange Einträge zu Ihrer normalen pagedown anzuzeigen/pageUp):

perf report | c++filt | less 
perf annotate function_name | c++filt | less 
# or: perf annotate -s function_name | c++filt | less 

Oder Sie können aktualisieren/neu kompilieren Ihre perf vorgeschlagen, wie durch billyw in his comment

4^Es scheint, Sie auf Ubuntu sind. Ich vermute, dass dies Ihr Problem und Lösung ist: https://stackoverflow.com/a/34061874/2166274 - Billyw 3. März 16 um 17:31