g++ (GCC) 5.2.0
clang version 3.7.1 (tags/RELEASE_371/final)
GNU gdb (GDB) 7.12
Gdb is unable to locate the definition of std::string when compiled with clang for some reason. I have custom compiled and build gcc and clang as Centos 6.5 comes with older version of gcc.
Example code
#include <string>
int main()
{
std::string s("This is a string");
return 0;
}
Compile with g++ and debug - works just fine
[~]$ g++ -ggdb3 -std=c++14 stl.cpp
[~]$ gdb a.out
GNU gdb (GDB) 7.12
Reading symbols from a.out...done.
(gdb) break main
Breakpoint 1 at 0x400841: file stl.cpp, line 5.
(gdb) r
Starting program: /home/vagrant/a.out
Breakpoint 1, main () at stl.cpp:5
5 std::string s("This is a string");
(gdb) n
7 return 0;
(gdb) p s
$1 = {static npos = <optimized out>,
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x612c20 "This is a string"}, _M_string_length = 16, {
_M_local_buf = "\020\000\000\000\000\000\000\000\300\b@\000\000\000\000", _M_allocated_capacity = 16}}
(gdb)
Check that it is linking with my rpm build version of libstdc++ and not system
[~]$ ldd a.out
linux-vdso.so.1 => (0x00007ffd709e0000)
libstdc++.so.6 => /opt/spotx-gcc/lib64/libstdc++.so.6 (0x00007f29318fa000)
libm.so.6 => /lib64/libm.so.6 (0x00007f2931676000)
libgcc_s.so.1 => /opt/spotx-gcc/lib64/libgcc_s.so.1 (0x00007f293145f000)
libc.so.6 => /lib64/libc.so.6 (0x00007f29310cb000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2931c93000)
[~]$ objdump -T -C a.out
a.out: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 w D *UND* 0000000000000000 _Jv_RegisterClasses
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 std::allocator<char>::~allocator()
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 std::allocator<char>::allocator()
0000000000000000 DF *UND* 0000000000000000 GCC_3.0 _Unwind_Resume
0000000000400700 DF *UND* 0000000000000000 CXXABI_1.3 __gxx_personality_v0
All looks good now if I try the same with clang
[~]$ clang++ -std=c++14 -g stl.cpp
[~]$ gdb a.out
GNU gdb (GDB) 7.12
Reading symbols from a.out...done.
(gdb) break main
Breakpoint 1 at 0x400853: file stl.cpp, line 5.
(gdb) r
Starting program: /home/vagrant/a.out
Breakpoint 1, main () at stl.cpp:5
5 std::string s("This is a string");
(gdb) n
7 return 0;
(gdb) p s
$1 = <incomplete type>
(gdb)
Now I get an incomplete type - but the same libraries are being used
[~]$ ldd a.out
linux-vdso.so.1 => (0x00007fff5352d000)
libstdc++.so.6 => /opt/spotx-gcc/lib64/libstdc++.so.6 (0x00007f76b4023000)
libm.so.6 => /lib64/libm.so.6 (0x00007f76b3d9f000)
libgcc_s.so.1 => /opt/spotx-gcc/lib64/libgcc_s.so.1 (0x00007f76b3b88000)
libc.so.6 => /lib64/libc.so.6 (0x00007f76b37f4000)
/lib64/ld-linux-x86-64.so.2 (0x00007f76b43bc000)
[~]$ objdump -T -C a.out
a.out: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 w D *UND* 0000000000000000 _Jv_RegisterClasses
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main
0000000000000000 w D *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000000000 w D *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 std::allocator<char>::~allocator()
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.21 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 std::allocator<char>::allocator()
0000000000000000 DF *UND* 0000000000000000 GCC_3.0 _Unwind_Resume
0000000000400700 DF *UND* 0000000000000000 CXXABI_1.3 __gxx_personality_v0
Does anyone have any advice on where to look or something that I've missed. Both compilers are bootstrapped when building them - everything seems fine - it just appears to be std::string is not defined when using clang.
As ks1322 mentioned, this is because clang has decided not to emit debug information for libstc++.
You can force clang to do so by providing the following flag:
-D_GLIBCXX_DEBUG
I would only provide the flag for debug builds, but if debug is the default and release builds are a special target you should remove it:
release: CXXFLAGS := $(filter-out -D_GLIBCXX_DEBUG,$(CXXFLAGS)) -O2
This has fixed the same problem for me.
The last workaround mentioned in bug 24202 as linked by ks1322 is worth having a look at:
-fno-limit-debug-info will make your debug info larger, slow link (if you're not using -gsplit-dwarf) and debugger performance. But, yes, will address this.
Using -fno-limit-debug-info
forces Clang to emit debug information for e.g. std::string at the cost of a larger binary while preserving compatibility with other libraries and the rest of the system/SDK.
As ks1322 and Kevin mentioned, one can instead use -D_GLIBCXX_DEBUG
to switch libstdc++ into debug mode but this comes at a heavy price: any library you link against and with which you exchange STL containers (string, vector, etc.) must also be built with -D_GLIBCXX_DEBUG
. Meaning: your system/SDK must either support this with a separate set of libraries or you will have to rebuild them yourself.
I've reproduced this issue on Fedora with system clang.
It appears that clang is not emitting debug information for std::string
because it was told that libstdc++
provides it. See this comment from bug 24202:
Looks like you don't have debug information for libstdc++ installed:
Missing separate debuginfos, use: dnf debuginfo-install libgcc-5.1.1-4.fc22.x86_64 libstdc++-5.1.1-4.fc22.x86_64
Clang is not emitting debug information for std::string because it was told that libstdc++ provides it (but in your case, it's not installed); this is a debug size optimization that GCC apparently doesn't perform.
Does this work if you install the debug information for libstdc++?
I've installed debug info for libstdc++
with command dnf debuginfo-install libstdc++-6.2.1-2.fc25.x86_64
and that resolved the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With