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

Gcc 使用clang编译时无法查看std::string,gcc,gdb,clang++,Gcc,Gdb,Clang++,g++(GCC)5.2.0 clang版本3.7.1(标签/发行版\u 371/最终版) GNU gdb(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++(GCC)5.2.0

clang版本3.7.1(标签/发行版\u 371/最终版)

GNU gdb(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;
}
#包括
int main()
{
std::string s(“这是一个字符串”);
返回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) 
[~]$g++-ggdb3-std=c++14 stl.cpp
[~]$gdb a.out
GNU gdb(gdb)7.12
从a中读取符号…完成。
(gdb)主断路器
断点1位于0x400841:文件stl.cpp,第5行。
(gdb)r
启动程序:/home/vagrant/a.out
断点1,stl.cpp处的main():5
5 std::string s(“这是一个字符串”);
(gdb)n
7返回0;
(gdb)p s
$1={静态NPO=,,
_M_dataplus={={},},{M_p=0x612c20“这是一个字符串”},{M_字符串长度=16{
_M_local_buf=“\020\000\000\000\000\000\000\000\000\300\b@\000\000\000\000\000”
(gdb)
检查它是否链接到我的rpm构建版本的libstdc++而不是系统

[~]$ 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
[~]$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_.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、 输出:文件格式elf64-x86-64
动态符号表:
0000000000000000 w D*UND*0000000000000000启动__
0000000000000000 w D*UND*0000000000000000\u Jv\u注册类别
0000000000000000 DF*UND*0000000000000000 GLIBC_2.2.5____libc_start_main
0000000000000000 w D*UND*0000000000000000_ITM_注销可克隆
0000000000000000 w D*UND*0000000000000000\u ITM\u寄存器克隆表
0000000000000000 DF*UND*0000000000000000 GLIBCXX_3.4.21标准::__cxx11::基本_字符串::~basic_字符串()
0000000000000000 DF*UND*0000000000000000 GLIBCXX_3.4标准::分配器::~allocator()
0000000000000000 DF*UND*0000000000000000 GLIBCXX_3.4.21标准::cx11::基本字符串::基本字符串(字符常量*,标准::分配器常量&)
0000000000000000 DF*UND*0000000000000000 GLIBCXX_3.4标准::分配器::分配器()
0000000000000000 DF*UND*0000000000000000 GCC\u 3.0\u解除\u恢复
0000000000 400700 DF*UND*0000000000000000 CXXABI_1.3___gxx_个性_v0
如果我用叮当声也这么做,现在一切看起来都很好

[~]$ 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) 
[~]$clang++-std=c++14-gstl.cpp
[~]$gdb a.out
GNU gdb(gdb)7.12
从a中读取符号…完成。
(gdb)主断路器
断点1位于0x400853:文件stl.cpp,第5行。
(gdb)r
启动程序:/home/vagrant/a.out
断点1,stl.cpp处的main():5
5 std::string s(“这是一个字符串”);
(gdb)n
7返回0;
(gdb)p s
$1 = 
(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
[~]$ldd a.out
linux vdso.so.1=>(0x00007FFF53520000)
libstdc++.so.6=>/opt/spotx gcc/lib64/libstdc++.so.6(0x00007f76b4023000)
libm.so.6=>/lib64/libm.so.6(0x00007f76b3d9f000)
libgcc_.so.1=>/opt/spotx gcc/lib64/libgcc_.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、 输出:文件格式elf64-x86-64
动态符号表:
0000000000000000 w D*UND*0000000000000000启动__
0000000000000000 w D*UND*0000000000000000\u Jv\u注册类别
0000000000000000 DF*UND*0000000000000000 GLIBC_2.2.5____libc_start_main
0000000000000000 w D*UND*0000000000000000_ITM_注销可克隆
0000000000000000 w D*UND*0000000000000000\u ITM\u寄存器克隆表
0000000000000000 DF*UND*0000000000000000 GLIBCXX_3.4.21标准::__cxx11::基本_字符串::~basic_字符串()
0000000000000000 DF*UND*0000000000000000 GLIBCXX_3.4标准::分配器::~allocator()
0000000000000000 DF*UND*0000000000000000 GLIBCXX_3.4.21标准::cx11::基本字符串::基本字符串(字符常量*,标准::分配器常量&)
0000000000000000 DF*UND*0000000000000000 GLIBCXX_3.4标准::分配器::分配器()
0000000000000000 DF*UND*0000000000000000 GCC\u 3.0\u解除\u恢复
0000000000 400700 DF*UND*0000000000000000 CXXABI_1.3___gxx_个性_v0

有没有人建议我去哪里找,或者我错过了什么。这两个编译器在构建时都是自举的-一切似乎都很好-只是在使用clang时似乎没有定义std::string。

我在Fedora上用系统clang复制了这个问题

似乎clang没有为
std::string
发出调试信息,因为它被告知
libstdc++
提供了调试信息。请参见以下评论:

看起来您没有安装libstdc++的调试信息:

缺少单独的调试信息,请使用:dnf debuginfo安装libgcc-5.1.1-4.fc22.x86_64 libstdc++-5.1.1-4.fc22.x86_64

Clang没有为std::string发出调试信息,因为它是 被告知libstdc++提供了它(但在您的情况下,它不是 安装);这是一个调试大小优化,显然 没有表现

如果安装libstdc++的调试信息,这是否有效


我已经用命令dnf debuginfo install libstdc++-6.2.1-2.fc25.x86_64为
libstdc++
安装了调试信息,解决了这个问题。

正如ks1322所提到的,这是因为clang决定不为libstc++发出调试信息

您可以通过提供以下标志强制clang执行此操作:
-D_GLIBCXX_调试

release: CXXFLAGS := $(filter-out -D_GLIBCXX_DEBUG,$(CXXFLAGS)) -O2
sudo apt-get install libstdc++6-dbgsym