2008-10-31 8 views
185

Je veux examiner le contenu d'un std::vector dans GDB, comment le faire? Disons que c'est un std::vector<int> par souci de simplicité.Comment imprimer les éléments d'un vecteur C++ dans GDB?

+3

question similaires: http: // stackoverflow .com/questions/427589/inspection-standard-conteneur-stdmap-contenu-avec-gdb (le lien dans la réponse est très intéressant). –

+0

La nouvelle, meilleure façon de le faire est dans cette question: http://stackoverflow.com/questions/2492020/how-to-view-contents-of-stl-containers-using-gdb-7-x/2492341# 2492341 – dshepherd

+0

Non-vectoriel spécifique: https://stackoverflow.com/questions/427589/inspecting-standard-container-stdmap-contents-with-gdb –

Répondre

68

Pour voir vecteur std :: vecteur contenu myVector, type juste à GDB:

(gdb) print myVector 

Cela produira une sortie similaire à:

$1 = std::vector of length 3, capacity 4 = {10, 20, 30} 

Pour réaliser ci-dessus, vous avez besoin de gdb 7 (je l'ai testé sur gdb 7.01) et de python pretty-printer. Le processus d'installation de ceux-ci est décrit sur gdb wiki. De plus, après l'installation ci-dessus, cela fonctionne bien avec Eclipse interface graphique du débogueur C++ (et tout autre IDE utilisant GDB, comme je pense).

+8

Cela fonctionne bien tant que les éléments vectoriels sont directement interprétables. Mais cela n'aide pas si le vecteur contient des pointeurs vers les éléments d'intérêt. – wallyk

230

avec GCC 4.1.2, d'imprimer l'ensemble d'un std :: vecteur <int> appelé myVector, procédez comme suit:

print *(myVector._M_impl._M_start)@myVector.size() 

Pour imprimer uniquement les premiers éléments N, faire:

print *(myVector._M_impl._M_start)@N 

Explication

Ceci est probablement dépendant fortement de votre version du compilateur , Mais pour GCC 4.1.2, le pointeur sur le tableau interne est:

myVector._M_impl._M_start 

Et la commande GDB à imprimer N éléments d'un tableau à partir de pointeur P est:

print [email protected] 

Ou, en une forme courte (pour un .gdbinit standard):

p [email protected] 
+3

Hehe, c'est quelque chose qui m'a buggé avant, alors j'ai juste regardé ce matin et l'a ajouté comme mémo à moi-même (comme Jeff lui-même recommandé). –

+2

Aussi, si vous voulez juste un élément vectoriel particulier, myVector._M_impl._M_start + n (pour le nième élément) – mariner

+1

Ne fonctionne pas pour moi. 'Impossible d'évaluer la fonction - peut être en ligne' – wallyk

13

« Regarder » conteneurs STL alors que le débogage est un peu un problème. Voici 3 solutions différentes que j'ai utilisées dans le passé, aucune d'entre elles n'est parfaite.

1) Utiliser les scripts GDB de http://clith.com/gdb_stl_utils/ Ces scripts vous permettent d'imprimer le contenu de presque tous les conteneurs STL. Le problème est que cela ne fonctionne pas pour les conteneurs imbriqués comme une pile d'ensembles.

2) Visual Studio 2005 offre un support fantastique pour regarder des conteneurs STL. Cela fonctionne pour les conteneurs imbriqués, mais cela ne concerne que leur implémentation pour STL et ne fonctionne pas si vous placez un conteneur STL dans un conteneur Boost.

3) Écrivez votre propre fonction (ou méthode) d'impression pour l'élément spécifique que vous voulez imprimer pendant le débogage et utilisez 'call' en GDB pour imprimer l'élément. Notez que si votre fonction d'impression n'est pas appelée n'importe où dans le code, g ++ supprimera le code mort et la fonction 'print' ne sera pas trouvée par GDB (vous recevrez un message indiquant que la fonction est inline). Donc, compiler avec -fkeep-inline-fonctions

+6

Ce lien est un 404. – kristopolous

+1

http://clith.com/gdb_stl_utils/ – swalog

6

mettre le texte suivant dans ~ /.gdbinit

define print_vector 
    if $argc == 2 
     set $elem = $arg0.size() 
     if $arg1 >= $arg0.size() 
      printf "Error, %s.size() = %d, printing last element:\n", "$arg0", $arg0.size() 
      set $elem = $arg1 -1 
     end 
     print *($arg0._M_impl._M_start + $elem)@1 
    else 
     print *($arg0._M_impl._M_start)@$arg0.size() 
    end 
end 

document print_vector 
Display vector contents 
Usage: print_vector VECTOR_NAME INDEX 
VECTOR_NAME is the name of the vector 
INDEX is an optional argument specifying the element to display 
end 

Après avoir redémarré gdb (ou l'approvisionnement ~/.gdbinit), afficher l'aide associée comme celui-ci

gdb) help print_vector 
Display vector contents 
Usage: print_vector VECTOR_NAME INDEX 
VECTOR_NAME is the name of the vector 
INDEX is an optional argument specifying the element to display 

Exemple d'utilisation:

(gdb) print_vector videoconfig_.entries 0 
$32 = {{subChannelId = 177 '\261', sourceId = 0 '\000', hasH264PayloadInfo = false, bitrate = 0,  payloadType = 68 'D', maxFs = 0, maxMbps = 0, maxFps = 134, encoder = 0 '\000', temporalLayers = 0 '\000'}} 
+0

merci pour le code! Je suppose qu'il y a une faute de frappe et "print * ($ arg0._M_impl._M_start + $ elem) @ 1" devrait être "print * ($ arg0._M_impl._M_start + $ arg1) @ 1"? J'utilise la modification suivante: définir print_vector si $ argc == 2 si $ arg1> = $ arg0.size() - 1 printf "Erreur,% s.size() =% d, impression du dernier élément: \ n "," $ arg0 ", $ arg0.size() - 1 fin imprimer * ($ arg0._M_impl._M_start + $ arg1) @ 1 sinon imprimer * ($arg0._M_impl._M_start)@$ arg0.size() fin fin – user1541776

Questions connexes