2009-10-23 9 views
7

Que pensent les utilisateurs de gdb de ses capacités en ce qui concerne le débogage du code avec les templates et STL?Débogage du code C++ avec les templates et STL avec gdb

Utilisez-vous des astuces pour simplifier le débogage? Peut-être des scripts Python? Ou êtes-vous satisfait de la façon dont il est actuellement dans gdb (ver 6.x, pas encore essayé 7.x)?

Merci.

+0

Merci, Amro et dirkgently. Je m'attends à obtenir GDB 7.0 sur ma machine Debian (en cours d'exécution Testing) dans quelques jours. Pendant ce temps, j'essaie de voir comment faire les réglages dans .gdbinit juste de la bonne façon. Cordialement. – user193272

Répondre

5

Je suppose que vous voulez dire visualiser un meilleur code STL (et non la debug mode qui donnent itérateurs de sécurité et des contrôles d'exécution supplémentaires). Je ne sais pas si vous avez regardé ces postes:

En utilisant gdb

partir de la version 7.0, GDB inclut le support pour l'écriture de jolies-imprimantes en Python . De jolies imprimantes pour les classes STL sont distribuées avec GCC à partir de la version 4.5.0. La version la plus récente de ces imprimantes se trouve toujours dans libstdC++ svn repository. Pour activer ces imprimantes, vérifiez-les dernières imprimantes dans un répertoire local:

Aussi, essayez d'utiliser KDevelop/DDD si possible - ils l'aide.

1

Mon mode préféré d'utilisation de GDB est le mode GDB dans emacs. Vous obtenez un débogage visuel/source complet, une fenêtre de discussion, une fenêtre de pile (etc) ... Essayez-le, vous ne serez pas déçu.

Cela dit, GDB gère le débogage des conteneurs STL très bien sans add ons spéciaux ... Assurez-vous que vous construisez -g, et sans -ON (de toute nature) ...

0

ddd est super aussi - mon préféré!

1

Je ne suis pas sûr si vous êtes autorisé à ajouter du code, ou vous ne faites que déboguer le code, Désolé. J'ai écrit un utilitaire simple depuis un moment, j'espère que vous le trouverez utile. Vous pouvez imprimer le contenu des conteneurs standard facilement. Il n'y a pas de code spécifique de la plate-forme, un exemple d'utilisation (le test-pilote en fait):

#include <iostream> 
#include <fstream> 
#include <iomanip> 
#include <string> 

#include <vector> 
#include <list> 
#include <stack> 
#include <queue> 
#include <deque> 
#include <set> 
#include <map> 

#include <boost/array.hpp> 
#include <boost/assign.hpp> 
#include "streamer.hpp" 


const std::size_t consoleWidth = 80; 

std::ostream& newline_if_not_console(std::ostream& outputstream) 
{ 
    if(&outputstream != & std::cout) 
    { 
     outputstream << std::endl; 
    } 

    return outputstream; 
} 

void STL_test_ostream(std::ostream& out) 
{ 
    using namespace boost::assign; 
    using namespace streamer; 

    double iDoubleArray[] = {0.1, 1.2, 2.3, 3.4, 4.5}; // It could be of any type! 
    std::vector<int>    iVec; 
    std::list<int>     iList; 
    std::deque<int>     iDeque; 
    std::stack<int>     iStack; 
    std::queue<int>     iQueue; 
    std::priority_queue<int>  iPriorityQueue; 
    std::set<int>     iSet; 
    std::map<int, std::string>  iMap; 

    iVec   += 0, 1, 2, 3, 4, 5; 
    iList   += 0, 1, 2, 3, 4, 5; 
    iDeque   += 0, 1, 2, 3, 4, 5; 
    iStack   += 0, 1, 2, 3, 4, 5; 
    iQueue   += 0, 1, 2, 3, 4, 5; 
    iPriorityQueue += 0, 1, 2, 3, 4, 5; 
    iSet   += 0, 1, 2, 3, 4, 5; 
    insert(iMap) 
     ( 1 , "one" ) 
     ( 2 , "two" ) 
     ( 3 , "three") 
     ( 4 , "four" ) 
     ( 5 , "five" ); 

    out << std::string(consoleWidth, '=') << newline_if_not_console 
     << "STL Test..." << std::endl 
     << std::string(consoleWidth, '=') << newline_if_not_console; 

    out << "Native Array = " << iDoubleArray << std::endl; 
    out << "vector   = " << iVec   << std::endl; 
    out << "list   = " << iList   << std::endl; 
    out << "deque   = " << iDeque   << std::endl; 
    out << "queue   = " << iQueue   << std::endl; 
    out << "stack   = " << iStack   << std::endl; 
    out << "priority_queue = " << iPriorityQueue << std::endl; 
    out << "set   = " << iSet   << std::endl; 
    out << "map   = " << iMap   << std::endl; 

    out << std::string(consoleWidth, '=') << std::endl; 
} 

void Boost_test_ostream(std::ostream& out) 
{ 
    out << std::string(consoleWidth, '=') << newline_if_not_console 
    << "Boost Test..." << std::endl 
    << std::string(consoleWidth, '=') << newline_if_not_console; 

} 

int main() 
{ 
    std::ofstream stl("STL_test_ostream.txt"), 
       boost("Boost_test_ostream.txt"); 

    STL_test_ostream(std::cout); 
    Boost_test_ostream(std::cout); 

    STL_test_ostream(stl); 
    Boost_test_ostream(boost); 
} 

Je n'ai pas écrit le code encore pour les conteneurs Boost. Si tout va bien, je vais le faire quelque temps :)

Tout ce que vous avez à faire, est d'inclure ce fichier [ "streamer.hpp"]:

#ifndef DATASTRUCTRE_STREAMER 
#define DATASTRUCTRE_STREAMER 

#include <stack> 
#include <queue> 
#include <boost/array.hpp> 
#include <functional> 
#include <memory> 

namespace streamer 
{ 

    // one-value data structure streaming function 
    template <class Container, class Stream> 
    Stream& printOneValueContainer(Stream& outputstream, const Container& container) 
    { 
     Container::const_iterator beg = container.begin(); 

     outputstream << "["; 

     while(beg != container.end()) 
     { 
      outputstream << " " << *beg++; 
     } 

     outputstream << " ]"; 

     return outputstream; 
    } 

    // pair-value data structure streaming function 
    template <class Container, class Stream> 
    Stream& printPairValueContainer(Stream& outputstream, const Container& container) 
    { 
     Container::const_iterator beg = container.begin(); 

     outputstream << "["; 

     while(beg != container.end()) 
     { 
      outputstream << " " << "<" << beg->first << " , " << beg->second << ">"; 
      beg++; 
     } 

     outputstream << " ]"; 

     return outputstream; 
    } 



    /* 
    ************************************************************* 
    C++ Standard Library 
    ************************************************************* 
    */ 

    // Sequence Containers. 

    // vector, list, deque 
    template 
    < class Type 
    , template<class Type, class Allocator = std::allocator<Type> > class Container 
    , class Stream 
    > 
    Stream& operator<<(Stream& outputstream, const Container<Type>& container) 
    { 
     return printOneValueContainer(outputstream, container); 
    } 

    // Associative Containers. 

    // set, multiset 
    template 
     < class Key 
     , template<class KeyType, class Traits = std::less<KeyType>, class Allocator = std::allocator<KeyType> > class Container 
     , class Stream 
     > 
    Stream& operator<<(Stream& outputstream, const Container<Key>& container) 
    { 
     return printOneValueContainer(outputstream, container); 
    } 

    // map, multimap 
    template 
     < class Key, class Value 
     , template<class KeyType, class ValueType, class Traits = std::less<KeyType>, class Allocator = std::allocator<std::pair<const KeyType, ValueType> > > class Container 
     , class Stream 
     > 
    Stream& operator<<(Stream& outputstream, const Container<Key, Value>& container) 
    { 
     return printPairValueContainer(outputstream, container); 
    } 

    // Adapters. 

    // stack, queue 
    template < class Type, class Container > 
    const Container& container(const std::stack<Type, Container>& stack) 
    { 
     struct HackedStack : private std::stack<Type, Container> 
     { 
      static const Container& container(const std::stack<Type, Container>& stack) 
      { 
       return stack.*&HackedStack::c; 
      } 
     }; 

     return HackedStack::container(stack); 
    } 

    template < class Type, class Container > 
    const Container& container(const std::queue<Type, Container>& queue) 
    { 
     struct HackedQueue : private std::queue<Type, Container> 
     { 
      static const Container& container(const std::queue<Type, Container>& queue) 
      { 
       return queue.*&HackedQueue::c; 
      } 
     }; 

     return HackedQueue::container(queue); 
    } 

    template 
     < class Type 
     , template <class Type, class Container = std::deque<Type> > class Adapter 
     , class Stream 
     > 
    Stream& operator<<(Stream& outputstream, const Adapter<Type>& adapter) 
    { 
     return printOneValueContainer(outputstream, container(adapter)); 
    } 

    // priority_queue 
    template < class Type, class Container, class Compare > 
    const Container& container(const std::priority_queue<Type, Container, Compare>& priorityQue) 
    { 
     struct HackedProiorityQueue : private std::priority_queue<Type, Container, Compare> 
     { 
      static const Container& container(const std::priority_queue<Type, Container, Compare>& priorityQue) 
      { 
       return priorityQue.*&HackedProiorityQueue::c; 
      } 
     }; 

     return HackedProiorityQueue::container(priorityQue); 
    } 

    template < class Type, class Container, class Compare, class Stream > 
    Stream& operator<<(Stream& outputstream, const std::priority_queue<Type, Container, Compare>& adapter) 
    { 
     return printOneValueContainer(outputstream, container(adapter)); 
    } 

    /* 
    ************************************************************* 
    C++ Native Arrays 
    ************************************************************* 
    */ 

    template <class Type, std::size_t size, class Stream> 
    Stream& operator<<(Stream& outputstream, Type (&array)[size]) 
    { 
     outputstream << "["; 

     for(std::size_t i = 0; i < size; ++i) 
     { 
      outputstream << " " << array[i]; 
     } 

     outputstream << " ]"; 

     return outputstream; 
    } 

    /* 
    ************************************************************* 
     Boost 
    ************************************************************* 
    */ 
} 

#endif 
+0

Merci pour l'exemple de code et l'exemple. Actuellement, j'essaie de ne pas utiliser de code externe pour cela.Idéalement, j'aimerais que gdb le fasse nativement (une jolie impression a été mentionnée) ou crée un script pour gdb qui l'aide à le faire. D'autres réponses, je parie sur la nouvelle version de gdb pour être meilleur à cet égard. Et, d'ailleurs, j'écris mon propre code. Cordialement. – user193272

Questions connexes