代码之家  ›  专栏  ›  技术社区  ›  user193272

用GDB调试模板和STL的C++代码

  •  7
  • user193272  · 技术社区  · 17 年前

    这里的gdb用户对其使用模板和stl调试代码的能力有什么看法?

    您是否使用任何技巧使调试变得更简单?也许是一些Python脚本?或者您对目前在gdb中的情况满意吗(6.x版,还没有尝试过7.x版)?

    谢谢。

    5 回复  |  直到 17 年前
        1
  •  5
  •   dirkgently    17 年前

    我假设您的意思是更好地可视化STL代码(而不是 debug mode 它提供安全的迭代器和额外的运行时检查)。我不确定你是否看过这些帖子:

    使用GDB

    从7.0版开始,gdb包含了用python编写漂亮打印机的支持。STL类的漂亮打印机由4.5.0版的gcc分发。这些打印机的最新版本始终位于libstdc++svn存储库中。要启用这些打印机,请将最新的打印机签出到本地目录:

    另外,如果可能的话,尝试使用kdevelop/ddd——它们确实有帮助。

        2
  •  8
  •   Amro    17 年前

    这可能有帮助: GDB STL Support Tools

        3
  •  1
  •   dicroce    17 年前

    我最喜欢使用gdb的方法是在Emacs中使用gdb模式。您将获得完整的可视/源代码级调试、线程窗口、堆栈窗口(等等)。试试看,你不会失望的。

    这就是说,GDB处理STL容器的调试非常好,没有特殊的附加组件…只需确保你的建筑有-g,没有-on(任何类型的)……

        4
  •  1
  •   Khaled Alshaya    17 年前

    我不确定是否允许您添加代码,或者您只是在调试代码,对不起。我曾经写过一个简单的实用函数,希望你能发现它的用处。您可以轻松打印标准容器的内容。没有特定于平台的代码,使用示例(实际上是测试驱动程序):

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

    我还没有为Boost容器编写代码。希望有时间我会做的:)

    您所要做的就是包含这个文件[“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
    
        5
  •  0
  •   vehomzzz    17 年前

    DDD也很棒——我的最爱!