2017-01-19 1 views
4

г ++ (GCC) 5.2.0Не может просматривать зЬй :: строки при компиляции с лязгом

лязг версия 3.7.1 (теги/RELEASE_371/конечный)

GNU GDB (GDB) 7,12

По какой-то причине Gdb не может определить определение std :: string при компиляции с clang. У меня есть скомпилированные и собранные gcc и clang, поскольку Centos 6.5 поставляется со старой версией gcc.

Пример кода

#include <string> 

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

    return 0; 
} 

Compile с г ++ и отладки - работает просто отлично

[~]$ 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\[email protected]\000\000\000\000", _M_allocated_capacity = 16}} 
(gdb) 

Убедитесь, что он связывает с моей оборотов версии сборки 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 

Все выглядит хорошо сейчас, если я попробую то же самое с 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 не определяется.

ответ

8

Как упоминалось в ks1322, это связано с тем, что clang решил не генерировать отладочную информацию для libstC++.

Вы можете заставить лязг сделать это, предоставляя следующий флаг: -D_GLIBCXX_DEBUG

Я бы только обеспечить флаг для отладки строит, но если отладки по умолчанию и релиз сборки являются специальная цель, вы должны удалить его :

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

Это устранило ту же проблему для меня.

2

Я воспроизвел эту проблему на Fedora с системой clang.

Похоже, что clang не испускает информацию об отладке для std::string, потому что было сказано, что это libstdc++. Смотрите этот комментарий от bug 24202:

Похоже, у вас нет информации отладки для libstdC++ установлен:

Отсутствие отдельных debuginfos, использование: д.н.ф. DebugInfo установить libgcc-5.1.1-4.fc22 .x86_64 libstdC++ - 5.1.1-4.fc22.x86_64

Clang не излучающий отладочную информации для станда :: строки, так как это было сказано, что libstdC++ предоставляет его (но в вашем случае, это не установлен ) ; это оптимизация размера отладки, которую GCC, по-видимому, не выполняет.

Это работает, если вы устанавливаете информацию об отладке для libstdC++?

Я установил отладочную информацию для libstdc++ с командой dnf debuginfo-install libstdc++-6.2.1-2.fc25.x86_64 и решить эту проблему.

+0

Я построил gcc, а также RPM. Установка пакета отладки, который создает rpmbuild для gcc, не имеет никакого отношения к этому, но дает мне возможность посмотреть. Вероятно, нужно перекомпилировать gcc с флагом – Adrian