Another perf tools fixes for v6.11

Some more fixes about the build and a random crash:
 
 * 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
 
 Signed-off-by: Namhyung Kim <namhyung@kernel.org>
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQSo2x5BnqMqsoHtzsmMstVUGiXMgwUCZqls2wAKCRCMstVUGiXM
 g12aAQCovAOO6jC5GrzCS8KlBoHXplyGL1rscI2uZfOttotBnQEA875Ov6FNL9Ux
 u9oxHZOpN/U4Xnyeoj9c43ibae/urAQ=
 =LTu1
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2024-07-30 19:22:41 -07:00
commit e254e0c5ba
5 changed files with 117 additions and 13 deletions

View File

@ -82,7 +82,30 @@ FILES= \
FILES := $(addprefix $(OUTPUT),$(FILES))
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, 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

View File

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

View File

@ -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)

View File

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

View File

@ -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);