Ich habe die Anweisungen im GDB-Wiki befolgt, um die hübschen Python-Drucker zum Anzeigen von STL-Containern zu installieren. Mein ~/.gdbinit
sieht jetzt so aus:
python
import sys
sys.path.insert(0, '/opt/gdb_prettyprint/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
Wenn ich jedoch GDB starte und versuche, einen STL-Typ zu drucken, erhalte ich Folgendes:
print myString
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.:
$3 =
Kann jemand etwas Licht auf dieses werfen? Ich verwende Ubuntu 12.04, das mit GDB 7.4 geliefert wird.
Sie können mit dem unten stehenden GDB-Makro versuchen (es an Ihre ~/.gdbinit -Datei anhängen), um STL-Containerdaten und sogar deren Datenmitglieder zu drucken: https://Gist.github.com/ 3978082
Überprüfen Sie Ihre gcc-Version. Wenn es weniger als 4,7 ist, müssen Sie eine andere Datei "printer.py" verwenden. Laden Sie die Datei von http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/ herunter.
Es funktioniert einfach auf Ubuntu 17.04
Debian scheint die Dinge nun endlich richtig integriert zu haben:
#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));
}
Kompilieren:
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 der hübsche Drucker installiert ist mit:
info pretty-printer
Welches enthält die Zeilen:
global pretty-printers:
objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers:
libstdc++-v6
std::map
std::vector
Die Drucker werden von der Datei bereitgestellt:
/usr/share/gcc-7/python/libstdcxx/v6/printers.py
das mit dem Haupt-C++ - Bibliothekspaket libstdc++6
geliefert wird und unter libstdc++-v3/python/libstdcxx
im GCC-Quellcode liegt: 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 feststellt, dass die Datei das letzte Geheimnis ist, ist sie nicht in meinem Python-Pfad: python -c "import sys; print('\n'.join(sys.path))"
, muss sie also irgendwo fest codiert werden?
Wenn Sie nach der Python-Ausnahme info type _Rep
eingeben, informiert Sie gdb über die geladenen Klassen, die mit _Rep übereinstimmen. Diese Liste kann Ihnen helfen, herauszufinden, warum Python Ihren std::string class
nicht finden kann.
Ich war gerade mit Ihrem Problem konfrontiert und in meinem Fall befand sich ein intel c-Compiler, icc, der das Drucken ziemlich brach. Insbesondere der nicht qualifizierte icc-Name für std::string
führt zu:
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep;
aber hübscher Drucker suchte nach nicht qualifiziertem gcc-Namen:
std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep;
Um mein Problem zu lösen, habe ich die Klasse StdStringPrinter
in printers.py geändert und den nicht qualifizierten Namen der Zeichenfolge zum Typnamen hinzugefügt, um in gdb zu suchen. Ersetzen der Leitung:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
mit diesem:
reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer ()
Mit der von info type
erhaltenen Liste können Sie Ihre hübschen Drucker korrigieren, damit sie funktionieren.
Ich bin auf dieses Problem gestoßen und habe diese Seite aufgerufen, während ich versuchte, es herauszufinden. Ich habe es irgendwann repariert und dachte, es lohnt sich, meine Erfahrungen zu teilen.
Ich verwende gcc-5.2, also habe ich die gcc-5-branch-Version von pretty printer vom svn-Repo heruntergeladen. Ich musste jedoch diese zwei Mods machen:
1) Wenn Sie die .gitinit-Datei bearbeiten, wird der folgende Zusatz vorgeschlagen
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
Ich musste jedoch die Zeile register_libstdcxx_printers (None)
kommentieren, da ich ständig die Fehlermeldung erhielt, dass die libstdcxx_printers bereits registriert sind. Anscheinend 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-branch-Version auf dem svn-Repo. Ich habe seitdem keinen Fehler mehr und das Zeug wird jetzt gut gedruckt.
Hoffe das hilft.
Anstelle der Methoden, die in dem von Ihnen erwähnten Link aufgeführt sind, können Sie das Skript hier ausprobieren.
Gehen Sie wie folgt vor:
1) Laden Sie das Skript nach /your/path
. Benennen Sie ihn mit einem Namen, z. your_name.conf
.
2) Fügen Sie dem Home-Verzeichnis eine ~/.gdbinit
-Datei hinzu, falls Sie keine haben.
3) Fügen Sie eine Zeile source /your/path/your_name.conf
zu Ihrem ~/.gdbinit
hinzu.
4) Starten Sie gdb neu. pvector
ausprobieren
Hilfeinformationen finden Sie mit Befehlen wie help pvector
.
z.B.
pvector vec 5 # Prints element[5] in vec
pvector vec 5 10 # Prints elements in range [5, 10] in vec. (5, 6, 7, 8, 9, 10)
Zu Ihrer Information, das Skript fügt gdb mehrere Befehle (pvector
, plist
, pmap
usw.) hinzu, deren Funktion darin besteht, die Elemente von STL zu drucken. Es fügt auch print pretty
hinzu, was das Nice-Format wie folgt ergibt:
Wenn Sie wissen möchten, wie genau auf die Elemente von STL in gdb zugegriffen wird, lesen Sie einfach den Code der Befehle. Es gibt kein Geheimnis im Code. ^ _ ^
z.B. Auf Vektoren wird mit ._M_impl._M_start
zugegriffen.
p vec._M_impl._M_start + 4 # prints vec[4]
Ich denke, Sie verwenden eine Nicht-GNU-STL-Bibliothek oder möglicherweise einen sehr alten GCC libstdc++
. Der Typ einer normalen STL-Zeichenfolge in meinem Compiler lautet: std::basic_string<char, std::char_traits<char>, std::allocator<char> >
. Beachten Sie, dass dies nicht std::basic_string<char>
ist.
Der Python-Code enthält Folgendes:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
Hiermit wird ein verschachtelter Typ ::Rep
nach dem Typ des Basis-Strings gesucht. Die Fehlermeldung weist darauf hin, dass die String-Klasse der verwendeten fremden Bibliothek keinen ::Rep
-Typ hat.
Fehler, wie Sie sie oben geschrieben haben, werden normalerweise angezeigt, wenn das Programm LLVM-build ist (kompiliert von clang
) und Sie versuchen, es mit gdb
(das für GCC-Build-Programme verwendet werden sollte) zu debuggen von gdb
debuggt werden und umgekehrt. Um jedoch die oben genannten Probleme zu vermeiden, sollten Sie lldb
verwenden, wenn Sie clang
verwenden, und gdb
, wenn Sie g++
verwenden.