2009-04-29 8 views
1

Existe-t-il un moyen simple d'afficher les données dans une STL std::list<T> dans le débogueur Metrowerks CodeWarrior? Je peux afficher les données vers le début ou la fin de la liste en regardant des expressions telles queComment puis-je inspecter une liste STL dans le débogueur CodeWarrior?

instances->__list_imp.__list_deleter.end_.compressed_pair_imp.second_.prev_->data_ 

Je peux développer les petits signes « + » à côté des membres de struct marcher la liste un élément à la fois, mais c'est fastidieux, et après environ 20-30 éléments, l'arbre devient trop large pour la fenêtre du débogueur. La liste que j'examine comporte plus de 2 000 éléments.

Le débogueur CodeWarrior ne prend pas en charge les fonctions d'appel dans les expressions, donc je ne peux pas examiner la valeur de (++(++instances.begin())) ou quelque chose comme ça. Je ne peux que regarder les membres de la structure, qui ont des noms très longs et peu pratiques.

La fenêtre du débogueur est également limitée à environ 245 caractères, donc je ne peux pas écrire un script pour générer une expression ridiculement longue qui étendra au nœud Nième. J'essaie de déboguer un problème qui nécessite plusieurs heures de trempage pour être reproduit, donc tout ce qui nécessite d'ajouter du code de manière incrémentielle, de recompiler et de redéboguer ne sera pas très utile. S'il n'y a pas d'autre option, je devrais le faire.

Répondre

1

Ce n'est certainement pas un "moyen facile" (ce n'est peut-être pas plus simple que ce que vous faites avec "+"), mais je trouve cela plus utile que de regarder la vue dans certains cas. Il peut également vous permettre de déboguer dans de très mauvaises circonstances (où la vue de surveillance est presque non fonctionnelle pour une raison quelconque, ou où vous avez juste un fichier de vidage de mémoire binaire).

Avec un std :: liste, vous avez généralement une implémentation qui ressemble à quelque chose comme ceci en mémoire (consulter la liste < > pour plus de détails si nécessaire):

 
struct List 
{ 
    Node * next; 
    Node * prev; 
    size_t size; 
} 

template 
struct Node 
{ 
    Node * next; // last node will point to list rather than another node 
    Node * prev; // first node will point to list rather than another node 
    T payload; // e.g. in a std::list this would be a Foo * payload 
} 

Notez que suivant et précédent peut être dans la l'ordre inverse dans votre mise en œuvre.

& myList est essentiellement équivalent à "fin()" dans la plupart des implémentations.

Si vous utilisez le mode de mémoire, vous pouvez fouiner près & myList. Cela vous permettra de trouver la valeur du pointeur myList.prev ou myList.next, puis de modifier l'affichage de la mémoire pour voir cela. Vous avez ensuite atteint le dernier ou le premier noeud de votre liste, respectivement.

Une fois que vous arrivez à un nœud, vous pouvez regarder précédent, suivant, ou la charge utile, puis passez à prev ou suivant; faire mousser, rincer, répéter. Si vous vous retrouvez à & myList, vous savez que vous avez traversé le tout.

douloureux et ennuyeux? Peut-être. Mais vous vous familiarisez avec votre implémentation de stl, vous pouvez "voir" facilement les stomps possibles dans certains cas, et c'est une compétence utile à avoir quand toutes les autres possibilités s'envolent par la fenêtre.

(Prenez des notes de l'endroit où vous avez été, il est vraiment facile de se confondre.)

0

débogueurs pourraient certainement être beaucoup plus STL convivial. Je ne suis pas familier avec CodeWarrior spécifiquement, mais est-il le cas que vous ne pouvez pas appeler toutes les fonctions à partir de la fenêtre de débogage? Ou est-ce plus comme les autres débogueurs que j'ai utilisés, où vous (1) ne pouvez pas appeler des fonctions si le programme est déjà terminé (ABORT, segfault, ...), et (2) ne peut pas appeler des fonctions qui impliquent des extensions de gabarit (qui pourraient avoir besoin d'ajouter du code à l'image), mais (3) peut appeler des fonctions statiquement liées si le code est arrêté à un point d'arrêt?

Dans ce dernier cas, vous pouvez ajouter une ou plusieurs fonctions non basées sur un modèle à votre code pour copier un list<T> dans un tableau de type C de T, pour les types spécifiques qui vous intéressent. Si vous pouvez appeler ce genre de fonction à partir de votre fenêtre de débogage, faites cela, puis examinez les éléments du tableau pour savoir ce qu'il y a dans votre liste. Si vous ne pouvez pas appeler la fonction à partir de la fenêtre de débogage, vous devrez peut-être placer des appels à cette fonction dans votre code près du point d'erreur, et regarder les résultats. Si possible, protégez ces appels pour qu'ils ne soient appelés que lorsque vous avez défini un indicateur de débogage.

0

Il s'avère que le problème que j'avais était dû au fait que la liste avait plusieurs milliers d'éléments - il devrait avoir seulement quelques douzaines d'éléments, max.

Dans cette implémentation STL particulière, les pointeurs prev étaient stockés au décalage 0 de chaque nœud, de sorte que je pouvais suivre les liaisons par déréférencement répétitif. La monstruosité suivante regarde en arrière 20 liens:

********************((Metrowerks::node_base**********************)instances->__list_imp.__list_deleter.end_.compressed_pair_imp.second_) 

Après des liens vers l'avant est encore plus laid, puisque vous devez compenser par 4 octets après chaque déréférencer.