2015-12-11 2 views
6

Je voulais donner une perf à tirer un coup de profil certains programmes après avoir vu this parler de CppCon 2015. J'ai téléchargé la même bibliothèque de référence Google que le gars utilise dans la conversation, compilé mon programme avec les commutateurs appropriés , l'a lié à lui, puis utilisé perf pour enregistrer une course. L'option de rapport me donne ceci:Perf montre noms de fonctions mutilés

enter image description here

Comme vous pouvez voir les noms de fonction ne sont pas très lisibles. Je suppose que cela a à voir avec le mangling de nom C++. Fait intéressant, tous les noms de fonctions apparaissent correctement dans la vidéo pour le gars qui a donné la parole, mais pas pour moi. Je ne pense pas que les informations sur les symboles soient complètement manquantes car je ne verrais que les adresses mémoire dans ce cas. Pour une raison quelconque, perf ne peut pas "défaire" le nom C++ mangling pour moi, et c'est frustrant à regarder.

J'utilise gcc (g ++) La version 5.2.1, la version 4.2.6 est perf, et j'utilise ces commutateurs lors de la compilation:

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

La raison pour laquelle je ne me -fno-omit-frame-pointer est que j'utilise l'option -gdwarf-2 à la place, ce qui laisse des informations de débogage dans l'exécutable nain, ce qui est une alternative pour laisser le pointeur de cadre en place dans ce cas. Cela signifie également que je passe --call-graph "dwarf" à perf record. Quoi qu'il en soit, j'ai aussi essayé la méthode du pointeur de trame, et cela donne les mêmes résultats, donc ça n'a pas vraiment d'importance.

Alors pourquoi ne pas "annuler" le nom C++ mangling dans ce cas? Cela a-t-il quelque chose à voir avec l'utilisation de GCC, ce qui signifie bien sûr que j'utilise libstdC++?

+1

J'utilise Arch Linux et 'perf report' montre la démonétisation correcte des symboles. La page de manuel pour perf montre également qu'il existe une option '--demangle' qui est activée par défaut. Comme je ne vois pas le même comportement que vous, je n'ai pas de réponse, mais ce que vous voyez n'est pas un comportement par défaut attendu. –

+0

J'ai essayé d'ajouter ce commutateur manuellement, mais cela n'a rien changé. – adam10603

+0

@GabrielSouthern Utilisez-vous aussi gcc? – adam10603

Répondre

1

Lorsque perf report vous donne des noms comme déchiquetés _Z*, _ZN*, _ZL* etc, cela signifie que votre outil perf a été compilé sans accès à la fonction demangling ou désactivé. Il y a un code pour détecter demangler dans Makefile:

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

Les tests sont dans le répertoire tools/build/feature: http://elixir.free-electrons.com/linux/v4.2.6/source/tools/build/feature et fonctionnalité libelf est activée si le programme de test en utilisant la fonction elf_begin de libelf) (<libelf.h> header of elfutils package, -lelf linking) est disponible (et renvoie quelque chose? construit quand la machine du générateur de noyau ne peut pas exécuter les binaires elf de la machine cible directement avec ./test-libelf.bin et doit utiliser ssh sur une machine réelle ou sur un qemu utilisateur/système?).

Et le code dans la mise en œuvre de perf faire demangling (en utilisant cplus_demangle si HAVE_CPLUS_DEMANGLE_SUPPORT défini, sans utiliser demangle est NO_DEMANGLE est réglé après Makefile, en utilisant bfd.h et bfd_demangle fonction 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 

Cette tout est un peu étrange (toujours pas de fonction de démon C++ standard dans le monde Linux en post C++ 11 époque?). Et votre perf a été mal compilé ou mal configuré - c'est la raison pour laquelle il ne démange pas les noms.billyw linked answer par Michal Fapso qui dit que c'est le bug 1396654 d'ubuntu - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654.

Vous pouvez faire pirater la production de filtrage de perf avec c++filt programme, mais il vous empêche d'utiliser l'interface par défaut interactive TUI PERF (ajouter less ou écrire des fichiers texte pour afficher des listes très longues avec pageDown normal/pageUp):

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

Ou vous pouvez mettre à jour/recompiler votre perf comme suggéré par billyw dans his comment

4^Il semble que vous êtes sur Ubuntu. J'imagine que c'est votre problème et votre solution: https://stackoverflow.com/a/34061874/2166274 - billyw 3 mars 16 à 17:31