Re: [PATCH v1 09/13] perf symbol: Add abi::__cxa_demangle C++ demangling support

From: James Clark
Date: Fri Mar 31 2023 - 05:29:09 EST




On 30/03/2023 20:03, Ian Rogers wrote:
> On Thu, Mar 30, 2023 at 9:50 AM Ian Rogers <irogers@xxxxxxxxxx> wrote:
>>
>> On Thu, Mar 30, 2023 at 7:08 AM James Clark <james.clark@xxxxxxx> wrote:
>>>
>>>
>>>
>>> On 11/03/2023 06:57, Ian Rogers wrote:
>>>> Refactor C++ demangling out of symbol-elf into its own files similar
>>>> to other languages. Add abi::__cxa_demangle support. As the other
>>>> demanglers are not shippable with distributions, this brings back C++
>>>> demangling in a common case. It isn't perfect as the support for
>>>> optionally demangling arguments and modifiers isn't present.
>>>>
>>>> Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
>>>> ---
>>>> tools/perf/Makefile.config | 29 +++++++++---------
>>>> tools/perf/util/Build | 1 +
>>>> tools/perf/util/demangle-cxx.cpp | 50 ++++++++++++++++++++++++++++++++
>>>> tools/perf/util/demangle-cxx.h | 16 ++++++++++
>>>> tools/perf/util/symbol-elf.c | 37 +++++------------------
>>>> 5 files changed, 88 insertions(+), 45 deletions(-)
>>>> create mode 100644 tools/perf/util/demangle-cxx.cpp
>>>> create mode 100644 tools/perf/util/demangle-cxx.h
>>>>
>>>> diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
>>>> index 5756498248e0..fdeca45cf15f 100644
>>>> --- a/tools/perf/Makefile.config
>>>> +++ b/tools/perf/Makefile.config
>>>> @@ -906,6 +906,7 @@ ifdef BUILD_NONDISTRO
>>>> endif
>>>>
>>>> CFLAGS += -DHAVE_LIBBFD_SUPPORT
>>>> + CXXFLAGS += -DHAVE_LIBBFD_SUPPORT
>>>> ifeq ($(feature-libbfd-buildid), 1)
>>>> CFLAGS += -DHAVE_LIBBFD_BUILDID_SUPPORT
>>>> else
>>>> @@ -913,26 +914,24 @@ ifdef BUILD_NONDISTRO
>>>> endif
>>>> endif
>>>>
>>>> -ifdef NO_DEMANGLE
>>>> - CFLAGS += -DNO_DEMANGLE
>>>> -else
>>>> +ifndef NO_DEMANGLE
>>>> + $(call feature_check,cxa-demangle)
>>>> + ifeq ($(feature-cxa-demangle), 1)
>>>> + EXTLIBS += -lstdc++
>>>
>>> Hi Ian,
>>>
>>> I think cross compilation for arm on x86 isn't working after this change
>>> (at least on Ubuntu).
>>>
>>> Even with all of the arm64 libstdc++ stuff installed, you can only link
>>> to it using g++, but the perf build tries to link to it using gcc. Not
>>> sure it's some quirk with the search paths on Ubuntu or something else:
>>>
>>> $ aarch64-linux-gnu-gcc -lstdc++
>>>
>>> /usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-
>>> gnu/bin/ld: cannot find -lstdc++: No such file or directory
>>> collect2: error: ld returned 1 exit status
>>>
>>> g++ gets further:
>>>
>>> $ aarch64-linux-gnu-g++ -lstdc++
>>>
>>> ...
>>> (.text+0x20): undefined reference to `main'
>>> collect2: error: ld returned 1 exit status
>>>
>>> At the end of the perf build it looks like something similar is
>>> happening (with all the non interesting bits deleted):
>>>
>>> $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C tools/perf
>>> NO_BPF_SKEL=1 V=1
>>>
>>> aarch64-linux-gnu-gcc ... -o perf
>>>
>>> /usr/lib/gcc-cross/aarch64-linux-gnu/12/../../../../aarch64-linux-gnu/bin/ld:
>>> cannot find -lstdc++: No such file or directory
>>>
>>> If I build with NO_DEMANGLE=1 then the build works, but I think it would
>>> at be best to autodetect rather than have to do this. Or maybe even link
>>> at the end with g++ if we're going to use libstdc++?
>>
>> Hi James,
>>
>> sorry for the problems you are having, I'll see if I can get a repo. I
>> did add a feature test with this change in the same set:
>> https://lore.kernel.org/lkml/20230311065753.3012826-9-irogers@xxxxxxxxxx/
>> So it should be feature testing and only enabling when
>> HAVE_CXA_DEMANGLE_SUPPORT is present. Obviously something is up, so
>> I'll have a think about it.
>>
>> Thanks,
>> Ian
>
> Sorry to say I couldn't repro on Debian:
>
> $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C tools/perf
> NO_LIBELF=1 NO_LIBTRACEEVENT=1

If you have NO_LIBELF=1 it sets NO_DEMANGLE=1 automatically so it skips
the c++ linking step. If you run with V=1 you can see that it doesn't
have -lstdc++ on the last link line.

But, having said that, I went to make a full reproducer in docker but it
actually worked. Turns out that the issue was on my end. I'd used
update-alternatives for a different compiler version and looks like I
had half of one gcc and half of another g++. Completely my fault, sorry
for the noise!

James