96 votes

Inspecter le contenu d'un conteneur standard (std::map) avec gdb

Je suppose qu'il y a quelque chose comme ça :

#include <map>
int main(){
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;
}

J'aimerais pouvoir inspecter le contenu de la carte en exécutant le programme à partir de gdb.
Si j'essaie d'utiliser l'opérateur d'indice, j'obtiens :

(gdb) p m[1]
Attempt to take address of value not located in memory.

L'utilisation de la méthode de recherche ne donne pas de meilleurs résultats :

(gdb) p m.find(1)
Cannot evaluate function -- may be inlined

Existe-t-il un moyen d'y parvenir ?

0 votes

Pour imprimer tous les éléments sans tronquer les grandes cartes : stackoverflow.com/questions/47743215/ Plus axé sur "Cannot evaluate function maybe inlined" : stackoverflow.com/questions/40633787/

101voto

Jonathan Wakely Points 45593

Les réponses existantes à cette question sont très dépassée. Avec un GCC et une GDB récents, cela fonctionne tout simplement. TM grâce au support intégré de Python dans GDB 7.x et aux imprimantes libstdc++ fournies avec GCC.

Pour l'exemple de l'OP, j'obtiens :

(gdb) print m
$1 = std::map with 2 elements = {[1] = 2, [2] = 4}

Si cela ne fonctionne pas automatiquement pour vous, consultez le premier point de l'écran. Support STL de la page du wiki GDB.

Vous pouvez également écrire de jolies imprimantes Python pour vos propres types, cf. Jolie impression dans le manuel de GDB.

0 votes

Merci pour la réponse... en fait, la question elle-même est plutôt dépassée maintenant :)

3 votes

Oui, mais d'autres questions sont fermées parce qu'elles font double emploi, alors je voulais que les informations soient récentes.

1 votes

J'utilise GDB 7.2 et ce qui précède fonctionne ... si vous avez une petite collection. Je n'ai toujours pas trouvé le moyen d'imprimer l'élément 1543 d'un vecteur de 4K, à moins de recourir aux structures internes de l'implémentation STL.

35voto

jpalecek Points 31928

Je pense qu'il n'y en a pas, du moins pas si votre source est optimisée, etc. Cependant, il existe des macros pour gdb qui peuvent inspecter les conteneurs STL pour vous :

http://sourceware.org/ml/gdb/2008-02/msg00064.html

Cependant, je ne l'utilise pas, donc c'est à voir.

1 votes

Merci pour le lien ; le seul problème est que les macros dépendent de la version des bibliothèques stl, ce que je préfère éviter. +1

0 votes

Il est également un peu frustrant que des commandes comme "plist foo std::string" donnent des erreurs de syntaxe. Il semble que le type de valeur ne puisse pas contenir de ponctuation.

2 votes

Je n'ai pas essayé, mais si cela fonctionne de la même manière que pour le reste de GDB, mettre le nom entre guillemets devrait suffire.

25voto

Mr.Ree Points 5112

Il y a toujours l'évidence : Définissez votre propre fonction de test... Appelez-la depuis gdb. Par exemple :

#define SHOW(X) cout << # X " = " << (X) << endl

void testPrint( map<int,int> & m, int i )
{
  SHOW( m[i] );
  SHOW( m.find(i)->first );
}

int
main()
{
    std::map<int,int> m;
    m[1] = 2;
    m[2] = 4;
    return 0;  // Line 15.
}

Et :

....
Breakpoint 1 at 0x400e08: file foo.C, line 15.
(gdb) run
Starting program: /tmp/z/qD 

Breakpoint 1, main () at qD.C:15
(gdb) call testPrint( m, 2)
m[i] = 4
(*m.find(i)).first = 2
(gdb)

16 votes

Tant que le processus est en cours d'exécution. pas si utile pour les core-dumps.

2 votes

C'est un conseil utile pour déboguer GDB en général, et pas seulement avec STL. Je conserve toute une bibliothèque de fonctions d'aide GDB pour de nombreuses données difficiles à récupérer, par exemple write_cuda_array_as_image(). Notez que certains compilateurs supprimeront toutes les fonctions qui ne sont pas appelées, c'est pourquoi je place un appel à chaque fonction d'aide après le "return 0 ;" de ma main. De plus, le fait de les déclarer avec extern "C" facilite leur appel depuis gdb.

0 votes

@KyleSimek gcc supporte aussi ` __attribute__((used))` pour que l'éditeur de liens ne jette pas le symbole s'il n'est pas utilisé.

21voto

Employed Russian Points 50479

El stl-views.gdb était la meilleure réponse qui soit, mais plus maintenant.

Ce n'est pas intégré dans la ligne principale GDB pour l'instant, mais voici ce que vous obtenez en utilisant la commande 'archer-tromey-python'. branche :

(gdb) list
1   #include <map>
2   int main(){
3       std::map<int,int> m;
4       m[1] = 2;
5       m[2] = 4;
6       return 0;
7   }
(gdb) break 6
Breakpoint 1 at 0x8048274: file map.cc, line 6.
(gdb) run

Breakpoint 1, main () at map.cc:6
6       return 0;
(gdb) print m
$1 = std::map with 2 elements = {
  [1] = 2,
  [2] = 4
}
(gdb) quit

12voto

anand Points 199

Essayez De-Referencing STL Containers : sur cette page : http://www.yolinux.com/TUTORIALS/GDB-Commands.html

0 votes

Ceux-ci semblent être le business !

0 votes

Il s'agit en fait des mêmes macros que dans la réponse précédente :) Je crains qu'il n'y ait pas de solution plus simple.

1 votes

Quelle est la commande ? Vous avez réussi à nous faire dévier de notre route avec une grande quantité d'informations non pertinentes. Je ne suis pas intéressé par "Comment démarrer GDB" et les autres.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X