web-dev-qa-db-fra.com

Comment imprimer des conteneurs STL en GDB?

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.

40
Nick Hutchinson

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

9
Fei

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

4
Bingfeng

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.

2
Manuel Núñez

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.

2
bartgol

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:

 enter image description here

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]

1
Scott Yang

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.

1
Omnifarious

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

0
Ans