2012-07-23 17 views
38

Ich habe die Anweisungen on the GDB wiki befolgt, um die Python-Pretty-Drucker zum Anzeigen von STL-Containern zu installieren. Mein ~/.gdbinit sieht nun wie folgt aus:Wie Drucken von STL-Containern in 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 

Allerdings, wenn ich GDB laufen und versuchen, eine STL Art zu drucken, erhalte ich die folgende:

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

Kann jemand etwas Licht in diese? Ich benutze Ubuntu 12.04, das mit GDB 7.4 geliefert wird.

+5

Es könnte einfach sein, dass die C++ - Bibliothek ihre internen Typen und Member-Variablen geändert hat und das Python-Modul nicht mithalten konnte. –

+0

Könnten Sie bitte weitere Informationen einfügen, z. B. die C++ - Quelle, Compiler-Optionen usw.? Ich habe das gerade auf Ubuntu 12.04 getestet und es funktioniert für mich. – user1202136

+0

Funktioniert für mich mit Fedora 17. – Omnifarious

Antwort

1

Ich denke, Sie verwenden eine nicht-GNU-STL-Bibliothek oder möglicherweise eine sehr alte GCC libstdc++. Der Typ einer normalen STL-Zeichenfolge in meinem Compiler ist: std::basic_string<char, std::char_traits<char>, std::allocator<char> >. Beachten Sie, dass dies nicht std::basic_string<char> ist.

Der Python-Code hat dies darin:

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

Diese sehen eine verschachtelte Art bis ::Rep von was auch immer der Typ-Basis Zeichenfolge tatsächlich ist. Die Fehlermeldung besagt, dass die String-Klasse der von Ihnen verwendeten seltsamen Bibliothek keinen geschachtelten Typ ::Rep hat.

7

Sie können mit versuchen unter GDB Makro (hängen Sie ihn an Ihr ~/.gdbinit Datei) STL containter Typen Daten drucken und sogar ihre Datenelemente: https://gist.github.com/3978082

2

Wenn Sie geben info type _Rep nach dem Python Ausnahme, gdb informiert Sie über die geladenen Klassen, die mit _Rep übereinstimmen. Diese Liste könnte Ihnen helfen herauszufinden, warum Python Ihre std::string class nicht finden kann.

Ich habe gerade Ihr Problem konfrontiert und in meinem Fall war intel c Compiler, ICC, die schöne Druckerei brach. Insbesondere uneingeschränkte icc Namen für std::string Ergebnisse in:

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

aber ziemlich Drucker wurde für unqualifizierten gcc Namen suchen:

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

Was ich tat, um mein Problem zu lösen wurde modifiziert Klasse StdStringPrinter in printers.py , Hinzufügen des unqualifizierten Namens der Zeichenkette zum Typnamen, um in gdb zu suchen. Ersetzen Sie die Zeile:

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

mit diesem:

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

Mit der erhaltenen Liste von info type Sie Ihren hübschen Drucker reparieren könnten sie zu arbeiten.

0

Ich lief auf dieses Problem und traf diese Seite, während ich versuchte, es herauszufinden. Ich habe es schließlich behoben, und ich dachte, es wäre es wert, meine Erfahrung zu teilen.

Ich benutze gcc-5.2, also habe ich die GCC-5-Zweig-Version von Pretty Drucker aus dem Svn Repo heruntergeladen.Allerdings hatte ich diese beiden Mods zu tun:

1), wenn die .gitinit-Datei bearbeiten, der vorgeschlagene Zusatz ist

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 

Allerdings hatte ich die Linie register_libstdcxx_printers (None) zu kommentieren, da ich immer einen Fehler bekommen Er sagte mir, dass die libstdcxx_printers bereits registriert waren. Offensichtlich werden sie während der Importphase registriert.

2) Ich musste die Datei printers.py für std::set und std::map bearbeiten. Da der Typ _Rep_type in beiden privat ist. Insbesondere ersetze ich die Routine children in std::map und std::set durch die entsprechende in der Version von pretty printer aus der gcc-4_6-Zweigversion im svn repo. Habe seither keinen Fehler mehr, und Sachen werden jetzt gut ausgedruckt.

Hoffe, das hilft.

0

Es funktioniert nur auf Ubuntu 17.04

Debian scheint richtig nun endlich integriert Dinge:

#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)); 
} 

Compile:

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

Ergebnis:

(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} 

Wir können sehen, dass die hübsche Drucker mit installiert ist:

info pretty-printer 

, die die Zeilen enthält:

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

Die Drucker von der Datei provieded sind:

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

, die mit kommt das Haupt-C++ - Bibliothekspaket libstdc++6 und befindet sich unter libstdc++-v3/python/libstdcxx im GCC-Quellcode: https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release/libstdc%2B%2B-v3/python/libstdcxx/v6/printers.py#L244

TODO: wie GDB findet, dass die Datei das letzte Geheimnis ist, ist es nicht in meinem Python-Pfad: python -c "import sys; print('\n'.join(sys.path))" so muss es irgendwo fest codiert werden?

0

Fehler wie Sie post oben erscheint normalerweise, wenn das Programm LLVM-Build (kompiliert von clang) ist, und Sie versuchen, es durch gdb debuggen (die für GCC-Build-Programme verwendet werden soll). Theoretisch kann LLVM-Build-Programm von gdb debuggt werden und umgekehrt. Aber um Probleme wie oben zu vermeiden, sollten Sie lldb verwenden, wenn Sie clang verwenden, und sollten gdb verwenden, wenn Sie g++ verwenden.