Я хотел попробовать сделать некоторые программы после того, как увидел этот доклад из CppCon 2015. Я загрузил ту же библиотеку тестов Google, которую парень использовал в своем выступлении, скомпилировал мою программу с соответствующими переключателями, связал ее с ней, а затем использовал perf для записи прогона. Опция отчета дает мне это:
Как видите, названия функций не очень читабельны. Я предполагаю, что это связано с искажением имен в C ++. Интересно, что все имена функций правильно отображаются в видео для парня, который выступил с докладом, но не для меня. Я не думаю, что это случай полного пропуска символьной информации, потому что я видел бы только адреса памяти в этом случае. По какой-то причине perf не может «отменить» искажение имени в C ++ для меня, и это неприятно смотреть.
Я использую 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
Причина, по которой я не пользуюсь -fno-omit-frame-pointer
это то, что я использую -gdwarf-2
вместо этого опция, которая оставляет отладочную информацию в исполняемом файле dwarf, что является альтернативой для того, чтобы оставить указатель кадра на место в этом случае. Это также означает, что я прохожу --call-graph "dwarf"
в perf record
, Во всяком случае, я попробовал метод указателя кадра, и он дает те же результаты, так что это не имеет значения на самом деле.
Так почему же в этом случае перфект не «отменяет» искажение имени в C ++? Это как-то связано с использованием GCC, что, конечно, означает, что я использую libstdc ++?
когда perf report
дает вам искаженные имена, такие как _Z*
, _ZN*
, _ZL*
и т. д., это означает, что ваш perf
Инструмент был скомпилирован без доступа к функции разборки или с отключенным. В 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>
заголовок пакета elfutils, -lelf
связывание) доступно (и возвращает что-то? есть ли run test? как насчет кросс-сборок, когда машина ядра не может запустить двоичные файлы elf целевой машины напрямую с ./test-libelf.bin
и должен использовать ssh для реальной машины или какой-нибудь пользователь / системный qemu?).
И код в реализации Perf, чтобы сделать demangling (используя cplus_demangle
если определено HAVE_CPLUS_DEMANGLE_SUPPORT, не использовать demangle, если после Makefiles установлено NO_DEMANGLE, используя bfd.h и bfd_demangle
функция документы — 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 ++ 11 до сих пор нет стандартной функции разборки c ++ в мире Linux?). А также ваш перф был неверно скомпилирован или неверно настроен — это причина, почему он не разоблачает имена. billyw связанный ответ от Михал Фапсо который говорит, что это ошибка 1396654 Ubuntu — https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1396654.
Вы можете взломать фильтрацию вывода perf с помощью 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
Или вы можете обновить / перекомпилировать свой перф как предложено billyw в его комментарий
4 ^ Похоже, вы на Ubuntu. Я подозреваю, что это ваша проблема и решение: https://stackoverflow.com/a/34061874/2166274 — Billyw 3 марта ’16 в 17:31
Других решений пока нет …