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
Related
I'm trying to use std::future::wait_for(std::chrono::duration) in my application (in fact, I don't want to wait at all which makes this more frustrating, as you'll see), but in using anything from std::chrono, I am unable to run the application after cross-compiling it for my BeagleBone Black:
/usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `GLIBCXX_3.4.19' not found
Until I add the following lines to my code, this project compiles and runs great with an older version of GLIBCXX, but just to be able to check if a future's value is ready without blocking, I suddenly need all these newer libraries:
if (myFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
return true;
The BeagleBone Black comes with GLIBCXX_3.4.17 from GCC 4.6.3 - I've checked the C++ headers on the system, and as I suspected, all the functionality I need from the chrono library is there. So why does it ask for version 3.4.19?
I tried updating and upgrading Debian with sudo apt-get upgrade in the hopes that the newer libraries would be added. This had no effect. Besides, I would really like to be able to run on the stock image.
So I tried statically linking libstdc++ with -static-libstdc++ added to my LD flags. Now I'm apparently missing GLIBC-2.7 which can't be fixed in the same way with -static-libgcc
I'm out of ideas.
I was able to compile with a previous version of the function that required 3.4.19 by following steps in another answer.
Firstly, I checked what was needed from 3.4.19:
$ objdump -T myapp | grep "GLIBCXX_3.4.19"
00000000 DF *UND* 00000000 GLIBCXX_3.4.19 _ZNSt6chrono3_V212system_clock3nowEv
Then I searched for the same symbol in the library I have
$ objdump -T /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 | grep "_ZNSt6chrono3_V212system_clock3nowEv"
But this returned nothing. On a hunch, I tried finding just 'chrono' instead
$ objdump -T /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 | grep "chrono"
00080828 g DF .text 0000002a GLIBCXX_3.4.11 _ZNSt6chrono12system_clock3nowEv
0008ae38 g DO .rodata 00000001 GLIBCXX_3.4.11 _ZNSt6chrono12system_clock12is_monotonicE
Bingo. While it's not an exact match, it looked good enough for me. I added an assembly directive to my source file to update the linkage for the requested symbol.
__asm__(".symver _ZNSt6chrono3_V212system_clock3nowEv,_ZNSt6chrono12system_clock3nowEv#GLIBCXX_3.4.11");
While it now compiles and runs, I am unable to say for sure that this substitution works as I have other hurdles to get around however I think I'd be safe in saying it's a solution.
It works the ".symver" change, but it will break your std::chrono timers and dates if you compile it with >= GCC 4.8, because std::chrono ABI had changes.
It will run with systems like Ubuntu 12.04 (GCC 4.6.3) but date & time will not be showed correctly.
Wondering if it is possible to generate interleaved source and assembly from clang?
I am looking for something equivalent to gcc command (as demonstrated at http://www.fclose.com/240/generate-a-mixed-source-and-assembly-listing-using-gcc/)
gcc -Wa,-adhln -g source_code.c > assembly_list.s
I have visited Link: How do you get assembler output from C/C++ source in gcc? but it gets so far as to list the assembly - but no interleaving.
Also Visual Studio does give you pretty nice interleaved assembly output, details here: How to view the assembly behind the code using Visual C++?
Thank you for all the help.
Sarang
There seems to be a bug reported sometimes last year stating exactly this: http://llvm.org/bugs/show_bug.cgi?id=16647
Bug 16647 - No option to produce mixed source + assembly listing?
So since it is still NEW I guess clang does not have this supported yet.
As an alternative, how about compiling your code and then use objdump -S ? The output format is somewhat similar ...
As of August 2016, the bug that #dragosht mentioned still is open. However, there is a workaround offered by the linked bug 17465: clang -no-integrated-as -Xassembler -adhln. It disables the clang-integrated assembler and calls an external assembler, which hopefully supports the listing-generating options.
That works OK in Linux, but it doesn't work in Mac OS X (as of 10.11.6). The problem is that even the external assembler in OS X does not support the listing-generating options - you can check that with man as.
objdump -S is an alternative that also works well in Linux, but Mac OS X's alternative to objdump is otool, which does provide disassembly but not source interlacing. Hopefully that will change soon-ish, because otool seems to be on its way out while llvm grows its own objdump. See man llvm-otool.
Finally, for OS X the best option seems to be using gobjdump -S, from binutils. It can be installed with MacPorts or brew.
You can Generate Assembly Code from a .cc/.cpp source file by using this command
clang++ -c -S test-function.cc
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.
I'm debugging a nasty problem where #includeing a file(not anything I wrote, for the record) causes a crash in my program. This means, I have working and broken, with only one C(++) include statement changed. Some of the libraries I'm using don't have debugging information.
What I would like to do is get GDB to output every line of C++ executed for the program run, and x86 instructions where not available to a textfile in such a format that I can diff the two outputs and hopefully figure out what went wrong.
Is this easily possible in GDB?
You can check the difference between the pre-processed output in each version. For example:
gcc -dD -E a.cc -o a.pre
gcc -dD -E b.cc -o b.pre
diff -u a.pre b.pre
You can experiment with different "-d" settings to make that more verbose/concise. Maybe something in the difference of listings will be obvious. It's usually something like a struct which changes size depending on include files.
Failing that, if you really want to mess with per-instruction or line traces, you could probably use valgrind and see where the paths diverge, but I think you may be in for a world of pain. In fact you'll probably find valgrind finds your bug and then 100 you didn't know about :) I expect the problem is just a struct or other data size difference, and you won't need to bother.
You could get gdb to automate line tracing. It would be quite painful. Basically you'd need to script it to run "n" (next line) repeatedly until a crash, then check the logs. If you can script "b main", then "run", then infinite "n" that would do it. There's probably a built-in command to do it but I'm not aware of it.
I don't think GDB can do this; maybe a profile will help, though? Are you compiling with gcc? Look at the -p and -pf commands, I think those might be useful.
The disassemble command at the gdb prompt will disassemble the current function you are stopped in, but I don't think outputting the entire execution path is feasible.
What library are you including? If it is open source, you can recompile it with debugging symbols enabled. Also, if you're using Linux, most distributions have -dbg versions of packages for common libraries.
I compiled 2 different binaries on the same GNU/Linux server using g++ version 4.2.3.
The first one uses:
GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4
GLIBC_2.1.3
The second one uses:
GLIBC_2.0
GLIBC_2.2
GLIBC_2.1
GLIBCXX_3.4.9
GLIBCXX_3.4
GLIBC_2.1.3
Why the second binary uses GLIBCXX_3.4.9 that is only available on libstdc++.so.6.0.9 and not in libstdc++.so.6.0.8
What is the new feature generated by g++ that require an ABI break and force the system to have GLIBCXX_3.4.9?
Is there a way to disable this new feature to not require GLIBCXX_3.4.9?
To find out which of the listed GLIBCXX_3.4.9 symbol(s) your binary actually depends on, do this:
readelf -s ./a.out | grep 'GLIBCXX_3\.4\.9' | c++filt
Once you know which symbols to look for, you can trace back to the object which needs them:
nm -A *.o | grep _ZN<whatever>
Finally, to tie this back to source, you can do:
objdump -dS foo.o
and see which code is referencing the 3.4.9 symbol(s).
Since you asked for it, here are symbols having at least ABI version 3.4.9:
GLIBCXX_3.4.9 {
_ZNSt6__norm15_List_node_base4hook*;
_ZNSt6__norm15_List_node_base4swap*;
_ZNSt6__norm15_List_node_base6unhookEv;
_ZNSt6__norm15_List_node_base7reverseEv;
_ZNSt6__norm15_List_node_base8transfer*;
_ZNSo9_M_insertI[^g]*;
_ZNSt13basic_ostreamIwSt11char_traitsIwEE9_M_insertI[^g]*;
_ZNSi10_M_extractI[^g]*;
_ZNSt13basic_istreamIwSt11char_traitsIwEE10_M_extractI[^g]*;
_ZSt21__copy_streambufs_eofI[cw]St11char_traitsI[cw]EE[il]PSt15basic_streambuf*;
_ZSt16__ostream_insert*;
_ZN11__gnu_debug19_Safe_sequence_base12_M_get_mutexEv;
_ZN11__gnu_debug19_Safe_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb;
_ZN11__gnu_debug19_Safe_iterator_base16_M_detach_singleEv;
_ZN11__gnu_debug19_Safe_iterator_base12_M_get_mutexEv;
_ZNKSt9bad_alloc4whatEv;
_ZNKSt8bad_cast4whatEv;
_ZNKSt10bad_typeid4whatEv;
_ZNKSt13bad_exception4whatEv;
} GLIBCXX_3.4.8;
Run the file libstdc++-v3/config/abi/post/i386-linux-gnu/baseline_symbols.txt through c++filt, grepping for GLIBCXX_3.4.9 to make sense of those names (they look like wildcards only). I didn't do it because those names become quite long and nested. Later versions mostly include c++1x stuff. See the file libstdc++-v3/config/abi/pre/gnu.ver for the above. Read here about the VERSION linker script command.
Well the first question is how did you generate the above list.
One would assume that the compiler is deterministic and thus link binaries in the same way.
I assume I got marked down for not answering the question directly but a comment would be nice. But I still think you have not provided the correct information and it would be nice to see the output of the command that shows your problem.
Assuming you used ldd:
You would get an output that looked like this:
lib<X>.so.<ver> => /usr/lib/lib<X>.so.<verM> (<Addr>)
But this is not the end of the story.
Trying doing an ls on the file it may be a symbolic link
> ls /usr/lilb/lib<X>.so.<verM>
lrwxrwxrwx 1 root root <Date> /usr/lib/lib<X>.so.<verM> -> lib<X>.so.<verM>.<verm>.<verp>