web-dev-qa-db-fra.com

Inspection du contenu du conteneur standard (std :: map) avec gdb

Supposons avoir 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 exécutant le programme à partir de gdb.
Si j'essaie d'utiliser l'opérateur indice, je reçois: 

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

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

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

Y a-t-il un moyen d'accomplir cela? 

80
Paolo Tedesco

Je pense que non, du moins 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, alors YMMV

32
jpalecek

Les réponses existantes à cette question sont very obsolètes. Avec un récent GCC et GDB, ça marcheTM grâce au support Python intégré à GDB 7.x et aux jolies imprimantes libstdc ++ livrées avec GCC.

Pour l'exemple du PO, je reçois:

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

Si cela ne fonctionne pas automatiquement pour vous, voyez la première puce de la page Support STL du wiki GDB.

Vous pouvez aussi écrire de jolies imprimantes Python pour vos propres types, voir Pretty Printing dans le manuel GDB.

79
Jonathan Wakely

Il y a toujours une é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) 
20
Mr.Ree

Le stl-views.gdb était la meilleure réponse, mais plus maintenant.

Ceci n'est pas encore intégré dans la ligne principale GDB, mais voici ce que vous obtenez avec l'archer-tromey-python ' branch :

(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
20
Employed Russian

Essayez de dé-référencer des conteneurs STL: sur cette page: http://www.yolinux.com/TUTORIALS/GDB-Commands.html

12
anand

Vous pouvez contourner le second problème (Cannot evaluate function -- may be inlined) en vous assurant que votre compilateur utilise les informations de débogage DWARF-2 (ou 3 ou 4) lors de la compilation de votre programme. DWARF-2 inclut des informations en ligne, vous devriez donc pouvoir utiliser l'une des méthodes que vous avez décrites pour accéder aux éléments de votre conteneur std::map.

Pour compiler avec les informations de débogage DWARF-2, ajoutez l'indicateur -gdwarf-2 à votre commande de compilation.

0
Dan

Les réponses ci-dessus fonctionnent et bien. Si vous utilisez stl-views.gdb, voici la manière appropriée de visualiser les cartes et les éléments qu’elle contient . Laissez votre carte se présenter comme suit: std::map<char, int> myMap;

(gdb) pmap myMap char int

pmap <variable_name> <left_element_type> <right_element_type> pour voir les éléments de la carte.

J'espère que cela pourra aider.

0
Mazhar MIK