2009-10-23 2 views
7

여기서 gdb 사용자는 템플릿과 STL로 코드를 디버깅하는 것과 관련하여 어떻게 생각합니까?gdb로 템플릿과 STL로 디버깅 C++ 코드

디버깅을 더 간단하게하기 위해 어떤 트릭을 사용합니까? 아마도 일부 Python 스크립트입니까? 또는 gdb (ver 6.x, 아직 7.x를 사용해 보지 않은)에서 현재와 같은 방식으로 만족하고 있습니까?

감사합니다.

+0

감사 암로와 dirkgently : 희망, 나는 언젠가 그것을 할 수 있습니다 :

당신이해야 할 것을 모두이 파일 [ "streamer.hpp을"] 포함하는 것입니다. 나는 데비안 머신 (테스트 실행 중)에서 GDB 7.0을 구할 것으로 예상하고 있습니다. 한편, 나는 올바른 방법으로 .gdbinit에서 설정을 수행하는 방법을 보려고합니다. 감사합니다. – user193272

답변

5

난 당신이 더 나은 STL 코드를 시각화 의미한다고 가정하고 (그리고 안전 반복자 추가 런타임 검사를주는 debug mode). 당신은이 게시물에보고 한 경우 나 확실하지 않다 : GDB

를 사용

버전 7.0을 시작으로, GDB는 파이썬에서 꽤-프린터를 쓰기에 대한 지원을 포함 . STL 클래스 용 예쁜 프린터는 4.5.0 버전의 GCC와 함께 배포됩니다. 이 프린터의 최신 버전은 항상 libstdC++ svn 저장소에 있습니다. 이 프린터를 사용하려면, 체크 아웃 최신 프린터를 로컬 디렉토리 :

는, KDevelop/DDD 가능한 경우를 사용해보십시오 - 그들은 도움을한다.

1

GDB를 사용하는 가장 좋은 방법은 emacs의 GDB 모드입니다. 당신은 완전한 시각적/소스 레벨 디버깅, 스레드 창, 스택 창 (etc)을 얻습니다. 실전에 빠지면 실망하지 않을 것입니다. 말했다

은, GDB는 ... 그냥 -g 함께 구축하고 있는지 확인하고, (어떤 종류의) -ON없이 ... 특별한 추가 기능과 함께 잘 STL 컨테이너의 디버깅을 처리

0

ddd도 좋습니다 - 내 마음에 드는 것!

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

나는 아직 부스트 컨테이너에 대한 코드를 작성하지 않은 : 어떤 플랫폼 특정 코드, 사용의 예 (실제로 테스트 드라이버)가 없습니다.

#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

코드 샘플과 예제를 보내 주셔서 감사합니다. 현재이 모든 외부 코드를 사용하지 않으려 고합니다.이상적으로, 나는 gdb를 네이티브로 (예쁜 인쇄가 언급되었다)하거나 gdb를위한 스크립트를 만들어서 도움을주고 싶다. 다른 응답에서, 나는이 점에서 더 나은 gdb의 새로운 버전을 찾고있다. 그리고, btw, 나는 내 자신의 코드를 쓰고있다. 문안 인사. – user193272