使用模板调试C ++代码和使用gdb调试STL

时间:2009-10-23 01:08:31

标签: c++ debugging templates stl gdb

gdb用户在这里考虑使用模板和STL调试代码的能力是什么?

你是否使用任何技巧使调试变得更简单?也许是一些Python脚本?或者你对gdb目前的方式感到满意(版本6.x,还没试过7.x)?

感谢。

5 个答案:

答案 0 :(得分:8)

这可能会有所帮助: GDB STL Support Tools

答案 1 :(得分:5)

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

  

使用gdb

     

从7.0版开始,GDB支持在Python中编写漂亮的打印机。 STL类的漂亮打印机与GCC 4.5.0版一起发布。这些打印机的最新版本始终存在于libstdc ++ svn存储库中。要启用这些打印机,请将最新的打印机签出到本地目录:

另外,如果可能的话,尝试使用KDevelop / DDD - 他们会提供帮助。

答案 2 :(得分:1)

我最喜欢使用GDB的方法是在emacs中使用GDB模式。你得到完整的视觉/源代码级调试,线程窗口,堆栈窗口(等)......试一试,你不会失望。

也就是说,GDB处理STL容器的调试就好了,没有特别添加......只要确保你用-g构建,没有-ON(任何类型)......

答案 3 :(得分:1)

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

#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

答案 4 :(得分:0)

ddd太棒了 - 我最喜欢的!