perf build-ids: Fall back to debuginfod query if debuginfo not found

During a perf-record, use the -ldebuginfod API to query a debuginfod
server, should the debug data not be found in the usual system
locations.  If successful, the usual $HOME/.debug dir is populated.

Tested with:

  $ find .
  .
  ./ctags-debuginfo-5.8-26.fc31.x86_64.rpm
  ./usr
  ./usr/lib
  ./usr/lib/debug
  ./usr/lib/debug/.build-id
  ./usr/lib/debug/.build-id/ca
  ./usr/lib/debug/.build-id/ca/46f6ae6a0cee57d85abc1d461c49074248908d
  ./usr/lib/debug/.build-id/ca/46f6ae6a0cee57d85abc1d461c49074248908d.debug
  ./usr/lib/debug/usr
  ./usr/lib/debug/usr/bin
  ./usr/lib/debug/usr/bin/ctags-5.8-26.fc31.x86_64.debug

  $ debuginfod  -F .
  ...

  $ rm -rf ~/.debug/ ; mkdir ~/.debug

  $ perf record make tags
    BUILD:   Doing 'make -j8' parallel build
    GEN      tags
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.107 MB perf.data (1483 samples) ]

  $ find ~/.debug | grep ctags
  /home/jolsa/.debug/usr/bin/ctags
  /home/jolsa/.debug/usr/bin/ctags/ca46f6ae6a0cee57d85abc1d461c49074248908d
  /home/jolsa/.debug/usr/bin/ctags/ca46f6ae6a0cee57d85abc1d461c49074248908d/elf
  /home/jolsa/.debug/usr/bin/ctags/ca46f6ae6a0cee57d85abc1d461c49074248908d/probes

  $ rm -rf ~/.debug/ ; mkdir ~/.debug

  $ DEBUGINFOD_URLS=http://localhost:8002 perf record make tags
    BUILD:   Doing 'make -j8' parallel build
    GEN      tags
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.108 MB perf.data (1531 samples) ]

  $ find ~/.debug | grep ctag
  /home/jolsa/.debug/usr/bin/ctags
  /home/jolsa/.debug/usr/bin/ctags/ca46f6ae6a0cee57d85abc1d461c49074248908d
  /home/jolsa/.debug/usr/bin/ctags/ca46f6ae6a0cee57d85abc1d461c49074248908d/debug
  /home/jolsa/.debug/usr/bin/ctags/ca46f6ae6a0cee57d85abc1d461c49074248908d/elf
  /home/jolsa/.debug/usr/bin/ctags/ca46f6ae6a0cee57d85abc1d461c49074248908d/probes

Note the 'debug' file is created in the last run.

Note that currently the debuginfo data are downloaded only on record path,
we still need add this support to perf build-id/report.. and test ;-)

Tested-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Frank Ch. Eigler <fche@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Frank Ch. Eigler 2020-08-13 10:22:04 +02:00 committed by Arnaldo Carvalho de Melo
parent a508d061ef
commit c7a14fdcb3
6 changed files with 43 additions and 1 deletions

View File

@ -98,7 +98,8 @@ FEATURE_TESTS_EXTRA := \
llvm-version \
clang \
libbpf \
libpfm4
libpfm4 \
libdebuginfod
FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)

View File

@ -26,6 +26,7 @@ FILES= \
test-libelf-gelf_getnote.bin \
test-libelf-getshdrstrndx.bin \
test-libelf-mmap.bin \
test-libdebuginfod.bin \
test-libnuma.bin \
test-numa_num_possible_cpus.bin \
test-libperl.bin \
@ -157,6 +158,9 @@ $(OUTPUT)test-libelf-gelf_getnote.bin:
$(OUTPUT)test-libelf-getshdrstrndx.bin:
$(BUILD) -lelf
$(OUTPUT)test-libdebuginfod.bin:
$(BUILD) -ldebuginfod
$(OUTPUT)test-libnuma.bin:
$(BUILD) -lnuma

View File

@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
#include <elfutils/debuginfod.h>
int main(void)
{
debuginfod_client* c = debuginfod_begin();
return (long)c;
}

View File

@ -501,6 +501,14 @@ ifndef NO_LIBELF
CFLAGS += -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT
endif
ifndef NO_LIBDEBUGINFOD
$(call feature_check,libdebuginfod)
ifeq ($(feature-libdebuginfod), 1)
CFLAGS += -DHAVE_DEBUGINFOD_SUPPORT
EXTLIBS += -ldebuginfod
endif
endif
ifndef NO_DWARF
ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
msg := $(warning DWARF register mappings have not been defined for architecture $(SRCARCH), DWARF support disabled);

View File

@ -124,6 +124,8 @@ include ../scripts/utilities.mak
#
# Define LIBPFM4 to enable libpfm4 events extension.
#
# Define NO_LIBDEBUGINFOD if you do not want support debuginfod
#
# As per kernel Makefile, avoid funny character set dependencies
unexport LC_ALL

View File

@ -31,6 +31,10 @@
#include "probe-file.h"
#include "strlist.h"
#ifdef HAVE_DEBUGINFOD_SUPPORT
#include <elfutils/debuginfod.h>
#endif
#include <linux/ctype.h>
#include <linux/zalloc.h>
@ -636,6 +640,21 @@ static char *build_id_cache__find_debug(const char *sbuild_id,
if (realname && access(realname, R_OK))
zfree(&realname);
nsinfo__mountns_exit(&nsc);
#ifdef HAVE_DEBUGINFOD_SUPPORT
if (realname == NULL) {
debuginfod_client* c = debuginfod_begin();
if (c != NULL) {
int fd = debuginfod_find_debuginfo(c,
(const unsigned char*)sbuild_id, 0,
&realname);
if (fd >= 0)
close(fd); /* retaining reference by realname */
debuginfod_end(c);
}
}
#endif
out:
free(debugfile);
return realname;