it-swarm.com.de

Wie kann man STL-Container in GDB schön drucken?

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.

40
Nick Hutchinson

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

9
Fei

Ü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.

4
Bingfeng

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.

2
Manuel Núñez

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.

2
bartgol

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:

 enter image description here

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]

1
Scott Yang

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.

1
Omnifarious

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.

0
Ans