Commit e254e0c5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'perf-tools-fixes-for-v6.11-2024-07-30' of...

Merge tag 'perf-tools-fixes-for-v6.11-2024-07-30' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools

Pull perf tools fixes from Namhyung Kim:
 "Some more build fixes and a random crash fix:

   - Fix cross-build by setting pkg-config env according to the arch

   - Fix static build for missing library dependencies

   - Fix Segfault when callchain has no symbols"

* tag 'perf-tools-fixes-for-v6.11-2024-07-30' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools:
  perf docs: Document cross compilation
  perf: build: Link lib 'zstd' for static build
  perf: build: Link lib 'lzma' for static build
  perf: build: Only link libebl.a for old libdw
  perf: build: Set Python configuration for cross compilation
  perf: build: Setup PKG_CONFIG_LIBDIR for cross compilation
  perf tool: fix dereferencing NULL al->maps
parents c91a7dee d27087c7
Loading
Loading
Loading
Loading
+43 −10
Original line number Diff line number Diff line
@@ -82,7 +82,30 @@ FILES= \

FILES := $(addprefix $(OUTPUT),$(FILES))

# Some distros provide the command $(CROSS_COMPILE)pkg-config for
# searching packges installed with Multiarch. Use it for cross
# compilation if it is existed.
ifneq (, $(shell which $(CROSS_COMPILE)pkg-config))
  PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config
else
  PKG_CONFIG ?= pkg-config

  # PKG_CONFIG_PATH or PKG_CONFIG_LIBDIR, alongside PKG_CONFIG_SYSROOT_DIR
  # for modified system root, are required for the cross compilation.
  # If these PKG_CONFIG environment variables are not set, Multiarch library
  # paths are used instead.
  ifdef CROSS_COMPILE
    ifeq ($(PKG_CONFIG_LIBDIR)$(PKG_CONFIG_PATH)$(PKG_CONFIG_SYSROOT_DIR),)
      CROSS_ARCH = $(shell $(CC) -dumpmachine)
      PKG_CONFIG_LIBDIR := /usr/local/$(CROSS_ARCH)/lib/pkgconfig/
      PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/lib/$(CROSS_ARCH)/pkgconfig/
      PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/lib/$(CROSS_ARCH)/pkgconfig/
      PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/share/pkgconfig/
      PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/share/pkgconfig/
      export PKG_CONFIG_LIBDIR
    endif
  endif
endif

all: $(FILES)

@@ -147,7 +170,17 @@ $(OUTPUT)test-libopencsd.bin:

DWARFLIBS := -ldw
ifeq ($(findstring -static,${LDFLAGS}),-static)
DWARFLIBS += -lelf -lebl -lz -llzma -lbz2
  DWARFLIBS += -lelf -lz -llzma -lbz2 -lzstd

  LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw)
  LIBDW_VERSION_1 := $(word 1, $(subst ., ,$(LIBDW_VERSION)))
  LIBDW_VERSION_2 := $(word 2, $(subst ., ,$(LIBDW_VERSION)))

  # Elfutils merged libebl.a into libdw.a starting from version 0.177,
  # Link libebl.a only if libdw is older than this version.
  ifeq ($(shell test $(LIBDW_VERSION_2) -lt 177; echo $$?),0)
    DWARFLIBS += -lebl
  endif
endif

$(OUTPUT)test-dwarf.bin:
@@ -178,27 +211,27 @@ $(OUTPUT)test-numa_num_possible_cpus.bin:
	$(BUILD) -lnuma

$(OUTPUT)test-libunwind.bin:
	$(BUILD) -lelf
	$(BUILD) -lelf -llzma

$(OUTPUT)test-libunwind-debug-frame.bin:
	$(BUILD) -lelf
	$(BUILD) -lelf -llzma
$(OUTPUT)test-libunwind-x86.bin:
	$(BUILD) -lelf -lunwind-x86
	$(BUILD) -lelf -llzma -lunwind-x86

$(OUTPUT)test-libunwind-x86_64.bin:
	$(BUILD) -lelf -lunwind-x86_64
	$(BUILD) -lelf -llzma -lunwind-x86_64

$(OUTPUT)test-libunwind-arm.bin:
	$(BUILD) -lelf -lunwind-arm
	$(BUILD) -lelf -llzma -lunwind-arm

$(OUTPUT)test-libunwind-aarch64.bin:
	$(BUILD) -lelf -lunwind-aarch64
	$(BUILD) -lelf -llzma -lunwind-aarch64

$(OUTPUT)test-libunwind-debug-frame-arm.bin:
	$(BUILD) -lelf -lunwind-arm
	$(BUILD) -lelf -llzma -lunwind-arm

$(OUTPUT)test-libunwind-debug-frame-aarch64.bin:
	$(BUILD) -lelf -lunwind-aarch64
	$(BUILD) -lelf -llzma -lunwind-aarch64

$(OUTPUT)test-libaudit.bin:
	$(BUILD) -laudit
+28 −0
Original line number Diff line number Diff line
@@ -71,3 +71,31 @@ supported by GCC. UBSan detects undefined behaviors of programs at runtime.
  $ UBSAN_OPTIONS=print_stacktrace=1 ./perf record -a

If UBSan detects any problem at runtime, it outputs a “runtime error:” message.

4) Cross compilation
====================
As Multiarch is commonly supported in Linux distributions, we can install
libraries for multiple architectures on the same system and then cross-compile
Linux perf. For example, Aarch64 libraries and toolchains can be installed on
an x86_64 machine, allowing us to compile perf for an Aarch64 target.

Below is the command for building the perf with dynamic linking.

  $ cd /path/to/Linux
  $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C tools/perf

For static linking, the option `LDFLAGS="-static"` is required.

  $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- \
    LDFLAGS="-static" -C tools/perf

In the embedded system world, a use case is to explicitly specify the package
configuration paths for cross building:

  $ PKG_CONFIG_SYSROOT_DIR="/path/to/cross/build/sysroot" \
    PKG_CONFIG_LIBDIR="/usr/lib/:/usr/local/lib" \
    make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C tools/perf

In this case, the variable PKG_CONFIG_SYSROOT_DIR can be used alongside the
variable PKG_CONFIG_LIBDIR or PKG_CONFIG_PATH to prepend the sysroot path to
the library paths for cross compilation.
+19 −1
Original line number Diff line number Diff line
@@ -152,7 +152,17 @@ ifdef LIBDW_DIR
endif
DWARFLIBS := -ldw
ifeq ($(findstring -static,${LDFLAGS}),-static)
  DWARFLIBS += -lelf -lebl -ldl -lz -llzma -lbz2
  DWARFLIBS += -lelf -ldl -lz -llzma -lbz2 -lzstd

  LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw)
  LIBDW_VERSION_1 := $(word 1, $(subst ., ,$(LIBDW_VERSION)))
  LIBDW_VERSION_2 := $(word 2, $(subst ., ,$(LIBDW_VERSION)))

  # Elfutils merged libebl.a into libdw.a starting from version 0.177,
  # Link libebl.a only if libdw is older than this version.
  ifeq ($(shell test $(LIBDW_VERSION_2) -lt 177; echo $$?),0)
    DWARFLIBS += -lebl
  endif
endif
FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) $(DWARFLIBS)
@@ -296,6 +306,11 @@ endif

ifdef PYTHON_CONFIG
  PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) $(PYTHON_CONFIG_LDFLAGS) 2>/dev/null)
  # Update the python flags for cross compilation
  ifdef CROSS_COMPILE
    PYTHON_NATIVE := $(shell echo $(PYTHON_EMBED_LDOPTS) | sed 's/\(-L.*\/\)\(.*-linux-gnu\).*/\2/')
    PYTHON_EMBED_LDOPTS := $(subst $(PYTHON_NATIVE),$(shell $(CC) -dumpmachine),$(PYTHON_EMBED_LDOPTS))
  endif
  PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
  PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil
  PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --includes 2>/dev/null)
@@ -897,6 +912,9 @@ else
         PYTHON_SETUPTOOLS_INSTALLED := $(shell $(PYTHON) -c 'import setuptools;' 2> /dev/null && echo "yes" || echo "no")
         ifeq ($(PYTHON_SETUPTOOLS_INSTALLED), yes)
           PYTHON_EXTENSION_SUFFIX := $(shell $(PYTHON) -c 'from importlib import machinery; print(machinery.EXTENSION_SUFFIXES[0])')
           ifdef CROSS_COMPILE
             PYTHON_EXTENSION_SUFFIX := $(subst $(PYTHON_NATIVE),$(shell $(CC) -dumpmachine),$(PYTHON_EXTENSION_SUFFIX))
           endif
           LANG_BINDINGS += $(obj-perf)python/perf$(PYTHON_EXTENSION_SUFFIX)
	 else
           $(warning Missing python setuptools, the python binding won't be built, please install python3-setuptools or equivalent)
+26 −1
Original line number Diff line number Diff line
@@ -193,7 +193,32 @@ HOSTLD ?= ld
HOSTAR  ?= ar
CLANG   ?= clang

PKG_CONFIG = $(CROSS_COMPILE)pkg-config
# Some distros provide the command $(CROSS_COMPILE)pkg-config for
# searching packges installed with Multiarch. Use it for cross
# compilation if it is existed.
ifneq (, $(shell which $(CROSS_COMPILE)pkg-config))
  PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config
else
  PKG_CONFIG ?= pkg-config

  # PKG_CONFIG_PATH or PKG_CONFIG_LIBDIR, alongside PKG_CONFIG_SYSROOT_DIR
  # for modified system root, is required for the cross compilation.
  # If these PKG_CONFIG environment variables are not set, Multiarch library
  # paths are used instead.
  ifdef CROSS_COMPILE
    ifeq ($(PKG_CONFIG_LIBDIR)$(PKG_CONFIG_PATH)$(PKG_CONFIG_SYSROOT_DIR),)
      CROSS_ARCH = $(shell $(CC) -dumpmachine)
      PKG_CONFIG_LIBDIR := /usr/local/$(CROSS_ARCH)/lib/pkgconfig/
      PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/lib/$(CROSS_ARCH)/pkgconfig/
      PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/lib/$(CROSS_ARCH)/pkgconfig/
      PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/local/share/pkgconfig/
      PKG_CONFIG_LIBDIR := $(PKG_CONFIG_LIBDIR):/usr/share/pkgconfig/
      export PKG_CONFIG_LIBDIR
      $(warning Missing PKG_CONFIG_LIBDIR, PKG_CONFIG_PATH and PKG_CONFIG_SYSROOT_DIR for cross compilation,)
      $(warning set PKG_CONFIG_LIBDIR for using Multiarch libs.)
    endif
  endif
endif

RM      = rm -f
LN      = ln -f
+1 −1
Original line number Diff line number Diff line
@@ -1141,7 +1141,7 @@ int hist_entry__append_callchain(struct hist_entry *he, struct perf_sample *samp
int fill_callchain_info(struct addr_location *al, struct callchain_cursor_node *node,
			bool hide_unresolved)
{
	struct machine *machine = maps__machine(node->ms.maps);
	struct machine *machine = node->ms.maps ? maps__machine(node->ms.maps) : NULL;

	maps__put(al->maps);
	al->maps = maps__get(node->ms.maps);