2012-07-23 5 views
38

Я выполнил инструкции on the GDB wiki, чтобы установить python pretty-printers для просмотра контейнеров STL. Мой ~/.gdbinit теперь выглядит следующим образом:Как красиво печатать контейнеры STL в GDB?

python 
import sys 
sys.path.insert(0, '/opt/gdb_prettyprint/python') 
from libstdcxx.v6.printers import register_libstdcxx_printers 
register_libstdcxx_printers (None) 
end 

Однако, когда я отлаживать и попытаться напечатать тип STL, я получаю следующее:

print myString 
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.: 
$3 = 

Может кто-нибудь пролить некоторый свет на это? Я запускаю Ubuntu 12.04, который поставляется с GDB 7.4.

+5

Просто может быть, что библиотека C++ изменила свои внутренние типы и переменные-члены, а модуль Python не поддерживал. –

+0

Не могли бы вы вставить дополнительную информацию, такую ​​как источник C++, параметры компилятора и т. Д.? Я просто тестировал это на Ubuntu 12.04, и он работает для меня. – user1202136

+0

Работает для меня с Fedora 17. – Omnifarious

ответ

1

Я думаю, вы используете библиотеку не GNU STL, или возможно очень старый GCC libstdc++. Тип нормальной строки STL в моем компиляторе: std::basic_string<char, std::char_traits<char>, std::allocator<char> >. Обратите внимание, что это не std::basic_string<char>.

код Питон имеет это в нем:

reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer() 

Этот посмотреть вложенный тип ::Rep из независимо от типа базовой строки на самом деле. Сообщение об ошибке указывает, что класс строк какой-либо странной библиотеки, которую вы используете, на самом деле не имеет вложенного типа ::Rep.

7

Вы можете попробовать ниже GDB макрос (добавьте его в ~/.gdbinit файл) для печати типов STL containter данных и даже их члены данных: https://gist.github.com/3978082

2

Если вы наберете info type _Rep после Python exception, gdb сообщит вам о загруженных классах, которые соответствуют _Rep. Этот список поможет вам найти, почему python не может найти ваш std::string class.

Я только что столкнулся с вашей проблемой, и в моем случае был компилятор intel ccc, icc, который прервал печать. В частности, неквалифицированное МОЕ имя std::string результатов:

std::basic_string<char, std::char_traits<char>, std::allocator<char> >::std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep; 

но довольно принтер искал неквалифицированный Gcc имени:

std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep; 

Что я сделал, чтобы решить мою проблема была изменение класса StdStringPrinter в printers.py , добавляя неквалифицированное имя строки к typename для просмотра в gdb. Замена строки:

reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer() 

с этим:

reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer() 

С полученного списка из info type вы могли исправить свои красивые принтеры, чтобы заставить их работать.

0

Я столкнулся с этой проблемой и ударил эту страницу, пытаясь понять ее. Я, в конце концов, исправил это, и я подумал, что стоило бы поделиться моим опытом.

Я использую gcc-5.2, поэтому я загрузил версию прекрасного принтера gcc-5 из репозитория svn.Тем не менее, я должен был сделать эти две моды:

1) при редактировании файла .gitinit, предлагаемое дополнение является

python 
import sys 
sys.path.insert(0, '/home/bartgol/.gdb/gdb_printers/python') 
from libstdcxx.v6.printers import register_libstdcxx_printers 
register_libstdcxx_printers (None) 
end 

Однако, я должен был прокомментировать линию register_libstdcxx_printers (None), так как я постоянно получаю ошибку говоря, что libstdcxx_printers уже зарегистрированы. По-видимому, они регистрируются на этапе импорта.

2) Мне пришлось отредактировать файл printerers.py для std::set и std::map. Так как тип _Rep_type является приватным в обоих. В частности, я заменяю подпрограмму children на номера std::map и std::set с соответствующей версией довольно красивого принтера из версии ветвления gcc-4_6 в репозитории svn. С тех пор не было никакой ошибки, и теперь все печатает.

Надеюсь, это поможет.

0

Он просто работает на Ubuntu 17,04

Debian, кажется, наконец, интегрированные вещи правильно теперь:

#include <map> 
#include <utility> 
#include <vector> 

int main() { 
    std::vector<int> v; 
    v.push_back(0); 
    v.push_back(1); 
    v.push_back(2); 
    std::map<int,int> m; 
    m.insert(std::make_pair(0, 0)); 
    m.insert(std::make_pair(1, -1)); 
    m.insert(std::make_pair(2, -2)); 
} 

компилирования:

g++ -O0 -ggdb3 -o container.out -std=c++98 container.cpp 

Результат:

(gdb) p v 
$1 = std::vector of length 3, capacity 4 = {0, 1, 2} 
(gdb) p m 
$2 = std::map with 3 elements = {[0] = 0, [1] = -1, [2] = -2} 

Мы можем видеть, что довольно принтер установлен с:

info pretty-printer 

Который содержит следующие строки:

global pretty-printers: 
    objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers: 
    libstdc++-v6 
    std::map 
    std::vector 

принтеры provieded файлом:

/usr/share/gcc-7/python/libstdcxx/v6/printers.py 

, который поставляется с основной пакет библиотеки C++ libstdc++6 и находится под libstdc++-v3/python/libstdcxx в исходном коде GCC: https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244

TODO: как GDB обнаруживает, что файл является окончательным mistery, это не в моем пути Python: python -c "import sys; print('\n'.join(sys.path))", поэтому он должен быть где-то жестко запрограммирован?

0

Ошибки, подобные сообщению выше, обычно появляются, когда программа LLVM-build (скомпилирована clang), и вы пытаетесь отладить ее на gdb (что должно использоваться для программ GCC-build). Теоретически, программа LLVM-build может быть отлажена gdb и наоборот. Но , чтобы избежать проблем, как указано выше, вы должны использовать lldb, если используете clang, и должны использовать gdb, если используете g++.

Смежные вопросы