2015-12-11 3 views
6

Я хотел дать перфоманс для профайла некоторых программ после того, как увидел this разговор от CppCon 2015. Я загрузил ту же самую тестовую библиотеку Google, которую парень использует в разговоре, скомпилировал мою программу с соответствующими переключателями , связал его с ним, затем использовал perf для записи прогона. Вариант отчета дает мне это:Perf показывает измененные имена функций

enter image description here

Как вы можете видеть имена функций не очень читаемые. Я предполагаю, что это связано с изменением имени C++. Интересно, что все имена функций отображались правильно в видео для парня, который дал разговор, но не для меня. Я не думаю, что это случай полного отсутствия информации о символах, потому что в этом случае я буду видеть адреса памяти. По какой-то причине перфомант не может «отменить» имя C++ для меня, и это разочаровывает.

Я использую GCC (г ++) версии 5.2.1, парфюм является версия 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

Причина, почему я не использую -fno-omit-frame-pointer заключается в том, что вместо этого я использую параметр -gdwarf-2, который оставляет информацию об отладке в исполняемом карлике, что является альтернативой для оставления указателя фрейма в этом случае. Это также означает, что я пропускаю --call-graph "dwarf" до perf record. Во всяком случае, я также попробовал метод указателя рамки, и он дает те же результаты, поэтому это не имеет значения.

Итак, почему в этом случае перфорация «отменяет» имя C++? Имеет ли это какое-либо отношение к использованию GCC, что, конечно, означает, что я использую libstdC++?

+1

Я использую Arch Linux и 'perf report' показывает правильную демонтацию символов. Страница man для perf также показывает, что есть опция '--demangle', которая включена по умолчанию. Поскольку я не вижу того же поведения, что и у вас, у меня нет ответа, но то, что вы видите, не ожидается по умолчанию. –

+0

Я также попытался добавить этот переключатель вручную, но ничего не изменил – adam10603

+0

@GabrielSouthern Вы используете gcc? – adam10603

ответ

1

Когда perf report дает подогнанные имена, как _Z*, _ZN*, _ZL* и т.д., это означает, что ваш инструмент perf был собран без доступа к декодированию функции или она отключена. Существует код для обнаружения demangler в Makefiles:

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

Тесты находятся в каталоге tools/build/feature: http://elixir.free-electrons.com/linux/v4.2.6/source/tools/build/feature и libelf функция включена, если тестовая программа, используя elf_begin функцию libelf (<libelf.h> header of elfutils package, -lelf) Доступно (и возвращает что-то? Есть ли тест на прогон? строит, когда машина построителя ядра не может запускать целевые исполняемые файлы elf-файлов непосредственно с ./test-libelf.bin и должна использовать ssh для реальной машины или некоторого пользователя/системы qemu?).

И код в реализации перфорации делать декодирование (с помощью cplus_demangle если HAVE_CPLUS_DEMANGLE_SUPPORT определенно, используя не demangle в NO_DEMANGLE устанавливаются после Makefiles, используя bfd.h и bfd_demangle функцию 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 

Этого все немного странно (до сих пор нет стандартной функции C++ demangle в мире Linux в post C++ 11 эпохи?). И ваш перфомант был неправильно составлен или неправильно сконфигурирован - это причина, почему он не деманлинг имен.billyw linked answer от Michal Fapso, который говорит, что это ошибка 1396654 от ubuntu - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654.

Вы можете сделать хак фильтрации вывода перфорации с c++filt программы, но это помешает вам использовать интерактивный интерфейс по умолчанию 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 

Или вы можете обновить/перекомпилировать Perf как предложено billyw в his comment

4^оказывается вы на Ubuntu. Я подозреваю, что это ваша проблема и решение: https://stackoverflow.com/a/34061874/2166274 - billyw Мар 3 '16 в 17:31

Смежные вопросы