Re: [PATCH v1 0/2] perf build: Remove libunwind support

Ian Rogers
2026-03-27T20:37:34Z

On Fri, Mar 27, 2026 at 1:07 PM Arnaldo Carvalho de Melo
<acme@kernel.org> wrote:
>
> On Thu, Mar 26, 2026 at 03:51:19PM -0700, Namhyung Kim wrote:
> > On Sat, Mar 21, 2026 at 04:42:18PM -0700, Ian Rogers wrote:
> > > libunwind support exists for "--call-graph dwarf", however, libunwind
> > > support has been opt-in rather than opt-out since Linux v6.13 as libdw
> > > is preferred - commit 13e17c9ff49119aa ("perf build: Make libunwind
> > > opt-in rather than opt-out"). A problem with the libdw support was
> > > that it was slow, an issue fixed in Linux v7.0 in commit 6b2658b3f36a
> > > ("perf unwind-libdw: Don't discard loaded ELF/DWARF after every
> > > unwind"). As such libunwind support is now unnecessary.
> > >
> > > The patch series:
> > > https://lore.kernel.org/lkml/20260305221927.3237145-1-irogers@google.com/
> > > looked to make the libunwind support in perf similar to the libdw
> > > support, allow cross-architecture unwinding, etc. This was motivated
> > > by the perf regs conventions being altered by the addition of x86 APX
> > > support:
> > > https://lore.kernel.org/lkml/20260209072047.2180332-1-dapeng1.mi@linux.intel.com/
> > > It is necessary to translate the library's notion of registers to the
> > > perf register convention so that the stack unwinding state can be
> > > initialized. On this series it was stated that removing libunwind
> > > support from perf should be an option, rather than updating support:
> > > https://lore.kernel.org/lkml/abxs-2rozL1tBEO1@google.com/
> > > This was also what motivated making libunwind opt-in rather than
> > > opt-out.
>
> > > Given that 7 minor releases have happened with libunwind "deprecated"
> > > by making it opt-in, let's remove the libunwind support. There doesn't
> > > appear to be any disagreement to this on the mailing list.
>
> > I'm not sure if we want to remove it now. I think we need more time to
> > verify libdw unwinding is stable and fast enough. Also maybe we can
> > add build- or run-time warning when people try to use libunwind.
>
> We have:
>
> acme@x1:~/git/perf-tools$ perf -vv | grep LIBU
> libunwind: [ OFF ] # HAVE_LIBUNWIND_SUPPORT ( tip: Deprecated, use LIBUNWIND=1 and install libunwind-dev[el] to build with it )
> acme@x1:~/git/perf-tools$
>
> acme@x1:~/git/perf-tools$ perf check feature libunwind && echo perf built with libunwind
> libunwind: [ OFF ] # HAVE_LIBUNWIND_SUPPORT ( tip: Deprecated, use LIBUNWIND=1 and install libunwind-dev[el] to build with it )
> acme@x1:~/git/perf-tools$
>
> Building with both, as Ian mentioned ends up with:
>
> LD /tmp/build/perf-tools/util/perf-util-in.o
> ld: /tmp/build/perf-tools/util/unwind-libunwind.o: in function `unwind__get_entries':
> unwind-libunwind.c:(.text+0x2a0): multiple definition of `unwind__get_entries'; /tmp/build/perf-tools/util/unwind-libdw.o:unwind-libdw.c:(.text+0x940): first defined here
> make[4]: *** [/home/acme/git/perf-tools/tools/build/Makefile.build:164: /tmp/build/perf-tools/util/perf-util-in.o] Error 123
> make[3]: *** [/home/acme/git/perf-tools/tools/build/Makefile.build:158: util] Error 2
> make[2]: *** [Makefile.perf:797: /tmp/build/perf-tools/perf-util-in.o] Error 2
> make[1]: *** [Makefile.perf:289: sub-make] Error 2
> make: *** [Makefile:119: install-bin] Error 2
> make: Leaving directory '/home/acme/git/perf-tools/tools/perf'
> ⬢ [acme@toolbx perf-tools]$
>
> So what Namhyung is suggesting is to disable libdw when libunwind is
> asked for?
>
> I.e.
>
> alias m='rm -rf ~/libexec/perf-core/ ; make LIBUNWIND=1 NO_LIBDW=1 -k O=/tmp/build/$(basename $PWD)/ -C tools/perf install-bin && perf test "import python" && cat /tmp/build/$(basename $PWD)/feature/test-all.make.output' ; export PYTHONPATH=/tmp/build/$(basename $PWD)/python
>
> Which builds and ends up linking with both:
>
> ⬢ [acme@toolbx perf-tools]$ ldd ~/bin/perf | egrep unwind\|dw
> libunwind-x86_64.so.8 => /lib64/libunwind-x86_64.so.8 (0x00007fbf430b6000)
> libunwind.so.8 => /lib64/libunwind.so.8 (0x00007fbf4309b000)
> libdw.so.1 => /lib64/libdw.so.1 (0x00007fbf38570000)
> ⬢ [acme@toolbx perf-tools]$
>
> I.e. that NO_LIBDW isn't really disabling linking with it, just some
> features based on it, likely.
>
> Hum, we also have NO_LIBDW_DWARF_UNWIND, which probably is what we want
> here... nope:
>
> ⬢ [acme@toolbx perf-tools]$ alias m='rm -rf ~/libexec/perf-core/ ; make LIBUNWIND=1 NO_LIBDW_DWARF_UNWIND=1 -k O=/tmp/build/$(basename $PWD)/ -C tools/perf install-bin && perf test "import python" && cat /tmp/build/$(basename $PWD)/feature/test-all.make.output' ; export PYTHONPATH=/tmp/build/$(basename $PWD)/python
> ⬢ [acme@toolbx perf-tools]$ m
> rm: cannot remove '/home/acme/libexec/perf-core/scripts/python/Perf-Trace-Util/lib/Perf/Trace/__pycache__/Core.cpython-314.pyc': Permission denied
> make: Entering directory '/home/acme/git/perf-tools/tools/perf'
> BUILD: Doing 'make -j12' parallel build
> Warning: Kernel ABI header differences:
> diff -u tools/arch/x86/include/uapi/asm/svm.h arch/x86/include/uapi/asm/svm.h
>
> Auto-detecting system features:
> ... libdw: [ on ]
> ... glibc: [ on ]
> ... libelf: [ on ]
> ... libnuma: [ on ]
> ... numa_num_possible_cpus: [ on ]
> ... libpython: [ on ]
> ... libcapstone: [ on ]
> ... llvm-perf: [ on ]
> ... zlib: [ on ]
> ... lzma: [ on ]
> ... bpf: [ on ]
> ... libaio: [ on ]
> ... libzstd: [ on ]
> ... libopenssl: [ on ]
> ... rust: [ on ]
>
> INSTALL libsubcmd_headers
> INSTALL libperf_headers
> INSTALL libapi_headers
> INSTALL libsymbol_headers
> INSTALL libbpf_headers
> LD /tmp/build/perf-tools/util/perf-util-in.o
> ld: /tmp/build/perf-tools/util/unwind-libunwind.o: in function `unwind__get_entries':
> unwind-libunwind.c:(.text+0x2a0): multiple definition of `unwind__get_entries'; /tmp/build/perf-tools/util/unwind-libdw.o:unwind-libdw.c:(.text+0x940): first defined here
> make[4]: *** [/home/acme/git/perf-tools/tools/build/Makefile.build:164: /tmp/build/perf-tools/util/perf-util-in.o] Error 123
> make[3]: *** [/home/acme/git/perf-tools/tools/build/Makefile.build:158: util] Error 2
> make[2]: *** [Makefile.perf:797: /tmp/build/perf-tools/perf-util-in.o] Error 2
> make[2]: *** Waiting for unfinished jobs....
> make[1]: *** [Makefile.perf:289: sub-make] Error 2
> make: *** [Makefile:119: install-bin] Error 2
> make: Leaving directory '/home/acme/git/perf-tools/tools/perf'
> ⬢ [acme@toolbx perf-tools]$
>
> I expected NO_LIBDW_DWARF_UNWIND=1 would resolve this case, and maybe it
> should?
>
> Or maybe it did it in the past as by now it is just a comment:
>
> ⬢ [acme@toolbx perf-tools]$ git grep NO_LIBDW_DWARF_UNWIND
> tools/perf/Makefile.perf:# Define NO_LIBDW_DWARF_UNWIND if you do not want libdw support
> ⬢ [acme@toolbx perf-tools]$
>
> Its from:
>
> # Define NO_LIBDW_DWARF_UNWIND if you do not want libdw support
> # for dwarf backtrace post unwind.
>
> As we need libdw for 'perf probe', etc, so being able to disable it just
> for DWARF backtrace is what we need here to make them mutually
> exclusive, i.e. the default is for building with libdw for backtraces,
> but if the user asks for LIBUNWIND=1, then a warning that libdw won't be
> used for DWARF backtraces and select NO_LIBDW_DWARF_UNWIND?
>
> We could then have a regression test that builds perf with one, does
> some backtraces, then with the other, then compare? This would be
> followup work, if somebody has the cycles, but making them mutually
> exclusive should be doable with not that much work?
>
> This is an area that is tricky and since we _already_ have two
> implementations, the good thing for regression testing would be the
> compare their results until libunwind becomes completely rotten and
> unusable?

My series:
https://lore.kernel.org/lkml/20260305221927.3237145-1-irogers@google.com/
makes libdw and libunwind supported together:
https://lore.kernel.org/lkml/20260305221927.3237145-2-irogers@google.com/
"""
This commit refactors the DWARF unwind post-processing to be
configurable at runtime via the .perfconfig file option
'unwind.style', or using the argument '--unwind-style' in the commands
'perf report', 'perf script' and 'perf inject', in a similar manner to
the addr2line or the disassembler style.
"""
That series cleans up several other issues, which is why I think it is
worth landing while we wait for libdw to become stable.

Thanks,
Ian

> - Arnaldo