2009-10-23 10 views
7

¿Qué piensan los usuarios de gdb sobre sus capacidades en cuanto a depuración de código con plantillas y STL?depuración Código de C++ con plantillas y STL con gdb

¿Utiliza algún truco para simplificar la depuración? Tal vez algunos scripts de Python? ¿O está satisfecho con lo que está actualmente en gdb (ver 6.x, aún no lo ha probado 7.x)?

Gracias.

+0

Gracias, Amro y dirkgently. Estoy esperando obtener GDB 7.0 en mi máquina Debian (ejecutar Testing) en algunos días. Mientras tanto, estoy tratando de ver cómo hacer configuraciones en .gdbinit de la manera correcta. Atentamente. – user193272

Respuesta

5

Estoy asumiendo que te refieres a la visualización de código AWL mejor (y no el debug mode que dan iteradores de seguridad y los controles de tiempo de ejecución adicionales). No estoy seguro de si ha mirado estos mensajes:

Usando GDB

partir de la versión 7.0, el BGF incluye soporte para la escritura de pretty-impresoras en Python . Las impresoras bonitas para las clases de STL se distribuyen con GCC desde la versión 4.5.0. La versión más reciente de estas impresoras siempre se encuentra en el repositorio libstdC++ svn. Para habilitar estas impresoras y la salida hasta las últimas impresoras a un directorio local:

Además, trate de usar KDevelop/DDD si es posible - que ayudan.

1

Mi forma favorita de usar GDB es el modo GDB en emacs. Obtienes depuración completa de nivel visual/de fuente, ventana de subprocesos, ventana de pila (etc.) ... Pruébalo, no te decepcionará.

Dicho esto, el BGF maneja la depuración de contenedores STL muy bien con ninguna complementos especiales Añadir ... Sólo asegúrese de que usted está construyendo CON -g, y sin -ON (de cualquier tipo) ...

0

ddd también es genial, ¡mi favorito!

1

No estoy seguro de si se le permite agregar código, o simplemente está depurando el código, Lo siento. Escribí unas sencillas funciones de utilidad desde hace un tiempo, espero que lo encuentren útil. Puede imprimir el contenido de los contenedores estándar fácilmente. No hay un código específico de la plataforma, un ejemplo de uso (el conductor de pruebas en realidad):

#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); 
} 

no he escrito el código para recipientes Boost todavía. Con suerte, lo haré en algún momento :)

Todo lo que tiene que hacer, es incluir este archivo [ "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

Gracias por el ejemplo del código y el ejemplo. Actualmente estoy tratando de no usar ningún código externo para esto.Idealmente, me gustaría que gdb lo haga de forma nativa (se ha mencionado la impresión bonita) o crear un script para gdb que lo ayude a hacerlo. De otras respuestas, confío en que la nueva versión de gdb sea mejor a este respecto. Y, por cierto, estoy escribiendo mi propio código. Saludos. – user193272