gcc 使用clang编译时无法查看std::string

qpgpyjmq  于 2022-11-13  发布在  其他
关注(0)|答案(5)|浏览(457)

g++(通用条款)5.2.0
clang版本371(标签/版本_371/最终版)
GNU地理数据库(GDB)7.12
由于某些原因,Gdb在用clang编译时无法找到std::string的定义。我已经自定义编译并构建了gcc和clang,因为Centos 6.5附带了旧版本的gcc。
示例代码

#include <string>

int main()
{
    std::string s("This is a string");

    return 0;
}

用g++编译并调试--工作正常

[~]$ 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)

检查它是否链接到libstdc++的rpm构建版本,而不是系统

[~]$ 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

现在一切看起来都很好,如果我尝试与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)

现在我得到了一个不完整的类型-但是使用了相同的库

[~]$ 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

有没有人建议在哪里查找或者我错过了什么?两个编译器在构建它们的时候都是引导的-一切看起来都很好-只是看起来std::string在使用clang的时候没有定义。

yshpjwxd

yshpjwxd1#

正如ks1322所提到的,这是因为clang已经决定不为libstc++发出调试信息。
您可以通过提供以下标志强制clang执行此操作:-D_GLIBCXX_DEBUG
我只会为调试版本提供标记,但是如果调试是默认的,而发布版本是一个特殊的目标,那么您应该删除它:

release: CXXFLAGS := $(filter-out -D_GLIBCXX_DEBUG,$(CXXFLAGS)) -O2

这已经解决了我同样的问题。

gt0wga4j

gt0wga4j2#

ks 1322链接的bug 24202中提到的最后一个解决方法值得一看:
-fno-limit-debug-info会使你的调试信息变大,链接变慢(如果你没有使用-gsplit-dwarf的话),调试器性能变差。但是,是的,会解决这个问题。
使用-fno-limit-debug-info强制Clang发出调试信息,例如std::string,代价是使用更大的二进制文件,同时保持与其他库和系统/SDK的其余部分的兼容性。
正如ks 1322和Kevin所提到的,可以使用-D_GLIBCXX_DEBUG将libstdc++转换为debug mode,但代价很大:任何链接到的库以及与之交换STL容器(字符串、矢量等)的库也必须使用-D_GLIBCXX_DEBUG构建。您的系统/SDK必须通过一组单独的库来支持这一点,否则您将不得不自己重新构建它们。

avwztpqn

avwztpqn3#

我已经在Fedora上用系统叮当声重现了这个问题。
看起来clang没有发出std::string的调试信息,因为它被告知libstdc++提供了调试信息。请参见bug 24202的注解:
看起来您没有安装libstdc的调试信息:
缺少单独的调试函数,请用途:文件系统调试-安装
Clang没有发出std::string的调试信息,因为它被告知libstdc
提供了它(但在您的情况下,它没有安装);这是GCC显然不执行调试器大小优化。
如果您安装了libstdc++的调试信息,这是否有效?
我已经使用命令dnf debuginfo-install libstdc++-6.2.1-2.fc25.x86_64安装了libstdc++的调试信息,这解决了问题。

pod7payv

pod7payv4#

clang相信libstd++的调试符号是可用的,所以你必须安装它们。关于如何在Fedora上安装它们,请参见ks1322的答案。在Ubuntu上,运行:

sudo apt-get install libstdc++6-dbgsym

在那之后,一切都会好起来的。

  • 不要 * 定义_GLIBCXX_DEBUG,因为这将破坏libstdc++的abi。

-fno-limit-debug-info会让clang发出比所需的更大的调试信息,所以我也建议不要这样做。只要安装libstdc++的调试信息包就可以了。

zd287kbt

zd287kbt5#

对我来说:-fno-limit-debug-info是clang / clion的真实的解决方案。_GLIBCXX_DEBUG导致与某些库的链接错误
clang版本10.0.0- 4目标:x86_64-pc-linux-gnu线程型号:posix已安装目录:/usr/二进制文件
CLion 2022.1.3构建版本号CL-221.5921.27,构建日期:2022年6月21日

相关问题