Weird characters in perf output... - c++

I'm trying to debug a webkit build with Linux perf that I compiled with symbols.
The output of "perf report -g" has the symbols with half human readable and the other half alphanumeric values.
For example:
_ZN7WebCore12RenderObject18setAnimatableStyleEN3WTF10PassRefPtrINS_11RenderStyleEEE
|
|--91.30%-- _ZN7WebCore4Node14setRenderStyleEN3WTF10PassRefPtrINS_11RenderStyleEEE
| _ZN7WebCore7Element11recalcStyleENS_4Node11StyleChangeE
| _ZN7WebCore7Element11recalcStyleENS_4Node11StyleChangeE
| _ZN7WebCore7Element11recalcStyleENS_4Node11StyleChangeE
What's happening here?
What's _ZN7?
My hunch is that this is something to do with C++ and maybe I need to compile with more options to get the symbols to be represented in perf correctly.
ANY pointers here would be appreciated. I can't find anything about this anywhere in the documentation.

These are so-called "mangled names": The C++ compiler encodes type information into symbol names, so that the linker can correctly implement overloading, class scoping and namespaces without having to actually understand the C++ type system, and without having to support characters outside of basic alphanumerics and underscores.
You can turn these back into human-readable names with tools such as c++filt under Linux.
For example:
$ echo _ZN7WebCore12RenderObject18setAnimatableStyleEN3WTF10PassRefPtrINS_11RenderStyleEEE | c++filt
WebCore::RenderObject::setAnimatableStyle(WTF::PassRefPtr<WebCore::RenderStyle>)
Or in your case, perf report -g | c++filt will probably do what you want.

Related

Failure to demangle symbol name in library (nm, objdump, c++filt)

I noticed non-demangled functions in my output of perf script and originally thought perf might be doing something wrong.
But, looking deeper into some of the *.so files, I've been able to reproduce the problem with c++filt -t, nm -C, and objdump -D -C.
I'm a bit lost as to what could possibly be going wrong in the demangling process.
One of the symbols that isn't getting demangled is:
_ZZNK5Gaudi10Functional7details16MultiTransformerIFSt5tupleIJSt6vectorIN4LHCb14VPLightClusterESaIS6_EESt5arrayIjLm53EEEERK12EventContextRKNS5_8RawEventERK4DeVPENS0_6Traits4use_IJNS5_7DetDesc21useConditionHandleForIJSI_EEENSM_11BaseClass_tINSO_23ConditionAccessorHolderI10FixTESPathINS_9AlgorithmEEEEEEEEELb0EE7executeESE_ENKUlDpRT_E_clIJK21DataObjectWriteHandleIS8_S8_EKS15_ISA_SA_EEEEDaS12_
The library was compiled with GCC 10.1. But if I compile with clang 11, I can find the same symbol in objdump -D -C.
I'm a bit at a dead end now, so any suggestions as to what I could possibly check would be really appreciated. :)
Resolved by using the tool suggested in the comments.
llvm-cxxfilt also works and might be already available on some machines.
c++filt, nm, perf, and objdump use functionality that is implemented in libiberty which is part of GCC.
Thus I've filed a bug report there: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102851

Demangling with c++filt on windows - gnu-v3

I am trying to properly demangle some symbols taken from a DWARF output.
On Linux, when i do c++filt --format gnu-v3. I can convert _ZZNV9SomeClass5afuncEiE1x to SomeClass::afunc(int) volatile::x
On Windows, I have installed Mingw32 which includes c++filt. The same command line yield the input, which means it hasn't been able to demangle.
What could cause this?
I assumed that specifying the format (gnu-v3) would be enough to make it work cross platform.

How do you use c++filt with llvm-cov report?

I'm trying to use a demangler with the llvm-cov report tool. The following is the command I'm running:
llvm-cov report /path/to/executable -instr-profile /path/to/default.profdata /path/to/src/ -Xdemangler c++filt -Xdemangler -n
I've tried rearranging the options and have tried using "-Xdemangler=c++filt -Xdemangler=-n" instead, and also using --no-strip-underscore instead of -n. It does not complain about the demangler, whereas if I make an obvious error with the command syntax it does tell me, but the output is not demangled.
From the llvm-cov documentation:
-Xdemangler=< TOOL >|< TOOL-OPTION >
Specify a symbol demangler. This can be used to make reports more human-readable. This option can be specified multiple times to supply arguments to the demangler (e.g -Xdemangler c++filt -Xdemangler -n for C++). The demangler is expected to read a newline-separated list of symbols from stdin and write a newline-separated list of the same length to stdout.
I've used the following to ensure that c++filt works, and it does:
c++filt -n _ZN4core6ZipperC2ENSt3__110shared_ptrIN8core_gen14PlatformZipperEEE
Output:
core::Zipper::Zipper(std::__1::shared_ptr<core_gen::PlatformZipper>)
I have to use the -n option, or it will not demangle, but I'm at a loss for why llvm-cov does not seem to be using it correctly.
I've also tried using a shell script to try to capture the input llvm-cov gives to the demangler and write it to a file before invoking c++filt, but the file was empty when I looked after running the command.
Am I doing something wrong?
It appears use of demangled function names is not hooked in everywhere in llvm-cov.
This report (the -name-regex option is needed to produce function names) does respond to the -Xdemangler option:
llvm-cov report /path/to/exe -name-regex=\.* -instr-profile=default.profdata -Xdemangler=c++filt
I see it's fixed in https://reviews.llvm.org/rL294136

How may I determine the cxxabi before loading a shared object with dlopen()?

I would like to determine that I am loading a compatible binary before calling dlopen(). I want to determine the cxxabi level before I load the library.
You could scan the list of symbols used by the binary before opening it. I am not sure how to do this in a program, although you can read the source for readelf for hints.
Using readelf -d -s -W /usr/lib/libstdc++.so.6 | c++filt | less on a Linux system I see some symbols marked like this: __gnu_cxx::__verbose_terminate_handler()##CXXABI_1.3
However, I would probably just try dlopen() and if it returns NULL, use dlerror() to report an error, then let the user figure it out.

what is the 'what' command on AIX under LINUX

I am used to use what to find out some version string in my program, which is normal defined as a string in the c++ code, starting with "#(#)".
Now I cannot find it in Linux. Can anyone tell me what I am supposed to do? Thanks a lot!
The what command is part of the Source Code Control System (SCCS), which is not commonly available on Linux (if there is a Linux version at all). You can try to emulate it with the strings command:
strings a.out | fgrep '#(#)'
Reimplementations of what are available in CSSC (an SCCS-to-modern version control conversion package) and in BSD (source code).
try this
strings myprogram | grep '#('
As #larsmans said, what command is part of SCCS. Here is the link to the GNU replacement for SCCS
Additionally to the mention of SCCS, ident is the equivalent for RCS (and there are quite a few tools which use the same marker as RCS, CVS being the first one of these).
The following command gives most equivalent output compared to what
strings filename | grep -o \"\"#(#).*\"\" | sed 's/^\"#(#)//' | sed 's/\"$//'