J'ai suivi les instructions sur le wiki GDB pour installer les jolies imprimantes python permettant d'afficher les conteneurs STL. Mon ~/.gdbinit
ressemble maintenant à ceci:
python
import sys
sys.path.insert(0, '/opt/gdb_prettyprint/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
Cependant, lorsque j'exécute GDB et que j'essaie d'imprimer un type STL, j'obtiens ce qui suit:
print myString
Python Exception <class 'gdb.error'> No type named std::basic_string<char>::_Rep.:
$3 =
Quelqu'un peut-il nous éclairer? J'utilise Ubuntu 12.04, fourni avec GDB 7.4.
Vous pouvez essayer avec la macro GDB ci-dessous (ajoutez-la à votre fichier ~/.gdbinit) pour imprimer les données des types de conteneur STL et même leurs membres: https://Gist.github.com/3978082
Vérifiez votre version de gcc. S'il est inférieur à 4.7, vous devez utiliser un autre fichier printer.py. Obtenez le fichier de http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch/libstdc++-v3/python/ .
Cela fonctionne simplement sur Ubuntu 17.04
Debian semble avoir finalement intégré les choses correctement maintenant:
#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));
}
Compiler:
g++ -O0 -ggdb3 -o container.out -std=c++98 container.cpp
Résultat:
(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}
Nous pouvons voir que la jolie imprimante est installée avec:
info pretty-printer
Qui contient les lignes:
global pretty-printers:
objfile /usr/lib/x86_64-linux-gnu/libstdc++.so.6 pretty-printers:
libstdc++-v6
std::map
std::vector
Les imprimantes sont fournies par le fichier:
/usr/share/gcc-7/python/libstdcxx/v6/printers.py
qui est fourni avec le package de bibliothèque principal C++ libstdc++6
et se trouve sous libstdc++-v3/python/libstdcxx
dans le code source GCC: https://github.com/gcc-mirror/gcc/blob/gcc-6_3_0-release/libstdc%2B%2B- v3/python/libstdcxx/v6/printers.py # L244
TODO: Comment GDB trouve que ce fichier est le dernier mystère, ce n’est pas dans mon chemin Python: python -c "import sys; print('\n'.join(sys.path))"
, il doit donc être codé en dur quelque part?
Si vous tapez info type _Rep
après l'exception Python, gdb vous informera des classes chargées qui correspondent à _Rep. Cette liste pourrait vous aider à comprendre pourquoi python ne peut pas trouver votre std::string class
.
Je viens de faire face à votre problème et dans mon cas, c’est le compilateur Intel, cci, qui a cassé de jolies impressions. En particulier, un nom icc non qualifié pour std::string
se traduit par:
std::basic_string<char, std::char_traits<char>, std::allocator<char> >::std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep;
mais jolie imprimante cherchait un nom non qualifié gcc:
std::basic_string<char, std::char_traits<char>, std::allocator<char>::_Rep;
Ce que j'ai fait pour résoudre mon problème a été de modifier la classe StdStringPrinter
dans printers.py, en ajoutant le nom non qualifié de la chaîne au nom de type à rechercher dans gdb. Remplacement de la ligne:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
avec ça:
reptype = gdb.lookup_type (str (realtype) + '::' + str (realtype) + '::_Rep').pointer ()
Avec la liste obtenue à partir de info type
, vous pouvez réparer vos jolies imprimantes pour les faire fonctionner.
J'ai couru sur ce problème et ai frappé cette page en essayant de le comprendre. J'ai finalement résolu le problème et je pensais que cela valait la peine de partager mon expérience.
J'utilise gcc-5.2, j'ai donc téléchargé la version gcc-5-branch de jolie imprimante à partir du repo svn. Cependant, je devais faire ces deux mods:
1) lors de l’édition du fichier .gitinit, l’ajout suggéré est:
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
Cependant, je devais commenter la ligne register_libstdcxx_printers (None)
, car je continuais à avoir une erreur en me disant que les libstdcxx_printers étaient déjà enregistrés. Apparemment, ils sont enregistrés pendant la phase d'importation.
2) J'ai dû modifier le fichier printers.py pour std::set
et std::map
. Depuis le type _Rep_type
est privé dans les deux. En particulier, je remplace la routine children
dans std::map
et std::set
par celle correspondante dans la version de jolie imprimante à partir de la version de gcc-4_6-branch sur le référentiel svn. Depuis, aucune erreur ne s'est produite, et tout est bien imprimé maintenant.
J'espère que cela t'aides.
Au lieu des méthodes énumérées dans le lien que vous avez mentionné , vous pouvez essayer le script ici ,
Faites comme suit:
1) Téléchargez le script pour /your/path
. Nommez-le à un nom, par exemple. your_name.conf
.
2) Ajoutez un fichier ~/.gdbinit
au répertoire de base si vous n'en avez pas.
3) Ajoutez une ligne source /your/path/your_name.conf
à votre ~/.gdbinit
.
4) Redémarrez gdb. Essayez pvector
Vous pouvez trouver des informations d'aide avec des commandes telles que help pvector
.
par exemple.
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)
FYI, le script ajoute plusieurs commandes (pvector
, plist
, pmap
etc.) à gdb ayant pour fonction d’afficher les éléments de STL. Il ajoute également print pretty
, donnant le format Nice comme ceci:
De plus, si vous voulez savoir exactement comment accéder aux éléments de STL dans gdb, lisez simplement le code des commandes. Il n'y a pas de secret dans le code. ^ _ ^
par exemple. Les vecteurs .__ sont accessibles par ._M_impl._M_start
p vec._M_impl._M_start + 4 # prints vec[4]
Je pense que vous utilisez une bibliothèque non-GNU STL, ou éventuellement un très ancien code GCC libstdc++
. Le type d'une chaîne STL normale sur mon compilateur est: std::basic_string<char, std::char_traits<char>, std::allocator<char> >
. Notez que ce n'est pas std::basic_string<char>
.
Le code Python contient ceci:
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
Ceci recherche un type imbriqué ::Rep
quel que soit le type de chaîne de base. Le message d'erreur indique que la classe de chaîne de la bibliothèque étrange que vous utilisez n'a pas de type imbriqué ::Rep
.
Des erreurs telles que celles que vous postez ci-dessus apparaissent généralement lorsque le programme est LLVM-build (compilé par clang
) et que vous essayez de le déboguer par gdb
(qui devrait être utilisé pour les programmes GCC-build) . En théorie, le programme LLVM-build peut être débogué par gdb
, et vice versa. Cependant, pour éviter les problèmes tels que signalés ci-dessus, vous devez utiliser lldb
si vous utilisez clang
, et vous devez utiliser gdb
si vous utilisez g++
.