简体   繁体   English

Perf显示损坏的函数名称

[英]Perf shows mangled function names

I wanted to give perf a shot to profile some programs after I saw this talk from CppCon 2015. I downloaded the same Google benchmark library that the guy uses in the talk, compiled my program with the appropriate switches, linked it to it, then used perf to record a run. 在我看到CppCon 2015的这个演讲之后,我想对一些程序进行概述。我下载了那个人在谈话中使用的相同Google基准库,用适当的开关编译我的程序,将其链接到它,然后使用perf记录一次跑步。 The report option gives me this: 报告选项给了我这个:

在此输入图像描述

As you can see the function names are not very readable. 正如您所看到的,函数名称不是很易读。 I assume this has to do with C++ name mangling. 我认为这与C ++名称修改有关。 Interestingly, all the function names show up correctly in the video for the guy who gave the talk, but not for me. 有趣的是,所有的功能名称都在视频中正确显示给那个发表演讲的人,但不适合我。 I don't think it's a case of completely missing the symbol information because I would only see memory addresses in that case. 我不认为这是完全缺少符号信息的情况,因为在这种情况下我只会看到内存地址。 For some reason, perf can't "undo" the C++ name mangling for me, and this is frustrating to look at. 由于某种原因,perf不能“撤消”我的C ++名称,这看起来很令人沮丧。

I'm using gcc (g++) version 5.2.1, perf is version 4.2.6, and I use these switches when compiling: 我正在使用gcc(g ++)版本5.2.1,perf是版本4.2.6,我在编译时使用这些开关:

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

The reason why I don't use -fno-omit-frame-pointer is that I use the -gdwarf-2 option instead, which leaves debugging information in the dwarf executable, which is an alternative for leaving the frame pointer in place in this case. 我不使用-fno-omit-frame-pointer是我使用-gdwarf-2选项,它在矮人可执行文件中留下调试信息,这是将帧指针保留在此处的替代方法案件。 This also means I pass --call-graph "dwarf" to perf record . 这也意味着我将--call-graph "dwarf"传递给perf record Anyway, I tried the frame pointer method as well, and it gives the same results, so this doesn't matter really. 无论如何,我也尝试了帧指针方法,它给出了相同的结果,所以这并不重要。

So why doesn't perf "undo" the C++ name mangling in this case? 那么为什么在这种情况下不会“撤消”C ++名称错误? Does this have anything to do with using GCC, which of course means that I'm using libstdc++? 这与使用GCC有什么关系,这当然意味着我正在使用libstdc ++?

When perf report gives you mangled names like _Z* , _ZN* , _ZL* etc, it means that your perf tool was compiled without access to demangling function or with it disabled. perf report为您提供错误的名称,如_Z*_ZN*_ZL*等,这意味着您的perf工具编译时无法访问demangling函数或禁用它。 There is code to detect demangler in Makefiles: 有一些代码可以在Makefile中检测demangler:

http://elixir.free-electrons.com/linux/v4.2.6/source/tools/perf/Makefile.perf 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 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 are in the tools/build/feature directory: http://elixir.free-electrons.com/linux/v4.2.6/source/tools/build/feature and libelf feature is enabled if test program using elf_begin function of libelf ( <libelf.h> header of elfutils package , -lelf linking) is available (and returns something? is there run test? what about cross-builds when kernel builder machine can't run target machine elf binaries directly with ./test-libelf.bin and must use ssh to real machine or some user/system qemu?). 测试在tools/build/feature目录中: httpelf_begin ,如果测试程序使用libelf的elf_begin函数,则启用libelf功能( <libelf.h> elfutils包的头文件-lelf链接)是可用的(并返回一些内容?是否有运行测试?当内核构建器机器无法直接使用./test-libelf.bin运行目标机器elf二进制文件时,如何进行交叉构建? ./test-libelf.bin并且必须使用ssh到真机或某些用户/系统qemu?)。

And the code in perf implementation to do demangling (using cplus_demangle if HAVE_CPLUS_DEMANGLE_SUPPORT defined, using no demangle is NO_DEMANGLE is set after Makefiles, using bfd.h and bfd_demangle function docs - 2.3.1.24 bfd_demangle ): http://elixir.free-electrons.com/linux/v4.2.6/source/tools/perf/util/symbol-elf.c#L19 并且执行demangling的执行中的代码(如果定义了cplus_demangle则使用cplus_demangle ,使用no demangle是在Makefiles之后设置NO_DEMANGLE,使用bfd.h和bfd_demangle函数docs - 2.3.1.24 bfd_demangle ): http://elixir.free-electrons的.com / LINUX / v4.2.6 /源极/工具/ PERF / util的/符号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

This all is bit strange (still no standard c++ demangle function in Linux world in post C++11 epoch?). 这一切都有点奇怪(在C ++ 11时代后期的Linux世界中仍然没有标准的c ++ demangle函数?)。 And your perf was miscompiled or misconfigured - it is the reason why it does not demangle names. 并且你的性能被错误编译或配置错误 - 这就是为什么它不能解析名称的原因。 billyw linked answer by Michal Fapso that says this is bug 1396654 of ubuntu - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654 . billyw 联系Michal Fapso的 回答说这是ubuntu的错误1396654 - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654

You may do hack of filtering output of perf with c++filt program but it prevent you from using interactive default TUI interface of perf (add less or write to text files to view very long listings with normal pageDown/pageUp): 您可以使用c++filt程序来过滤perf的输出,但它会阻止您使用perf的交互式默认TUI接口(添加less或写入文本文件以查看具有正常pageDown / pageUp的非常长的列表):

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

Or you can update/recompile your perf as suggested by billyw in his comment 或者您可以按照billyw评论中的建议更新/重新编译您的性能

4^ It appears you're on Ubuntu. 4 ^看来你在Ubuntu上。 I suspect that this is your problem and solution: https://stackoverflow.com/a/34061874/2166274 – billyw Mar 3 '16 at 17:31 我怀疑这是你的问题和解决方案: https ://stackoverflow.com/a/34061874/2166274 - billyw 2016年3月3日17:31

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM