My favorites | Sign in
Project Home Downloads Wiki Issues Source
Project Information
Members
Featured
Downloads
Links
  • External links
  • MiLi

Library to debug STL containers, specially useful from GDB.

This project belongs to FuDePAN.

Introduction

This library helps to debug C++ applications that use STL. It's specially tuned to overcome the issues that GDB has as of version 6.8. Basically, the library provides functions to inspect and display STL containers.

Usage

Three functions are provided:

  • stl_element(container, id) that retrieves an element address from a container based on the id. The id type depends on the container type.
  • stl_print() and it's overloaded flavors:
    • stl_print(container) that dumps the container content.
    • stl_print(iterator) shows the element being iterated.
    • stl_print(used-defined-type) shows a user-defined type (if stl_to_cout was provided for such type, see below).
  • stl_size(container) that retrieves the number of elements of the container.

In order to use stl_debug, follow these steps:

  1. #include stl_debug.h in every file containing STL containers you will want to debug.
  2. #include stl_debug_impl.h once in some .cpp/.cc source file
  3. teach the library what containers (with what types) you will want to dump/access, registering the containers by using the STL_DEBUG_REGISTER_* macros (see below).
  4. define the STL_DEBUG_ENABLE macro, i.e. by addding -DSTL_DEBUG_ENABLE command line flag to g++
  5. of course, build with -g or -ggdb

Registering the containers to debug

Each STL container template instantiation that needs to be debugged has to be registered. For example, vector<int> needs to be registered.

In order to register the containers, call the registration macros in the file where the stl_debug_impl.h file was included, out of any function (at file level). There is a registration type macro for each container type.

The registration macros so far are:

  • STL_DEBUG_REGISTER_VECTOR(type) enables debugging of std::vector<type>.
  • STL_DEBUG_REGISTER_LIST(type) enables debugging of std::list<type>.
  • STL_DEBUG_REGISTER_SET(type) enables debugging of std::set<type>.
  • STL_DEBUG_REGISTER_MAP(key,type) enables debugging of std::map<key,type>.

If the type is a symbol declared in the private or protected part of a class, redeclare it with STL_DEBUG_PRIVATE or STL_DEBUG_PROTECTED macros, that replace private and protected respectively. When the library is disabled (i.e. STL_DEBUG_ENABLE is undefined), these macros expand to the proper public/protected access modifiers.

Using the debugging functions

Refer to the example for precise instructions.

The id parameter of stl_element() function depends on the container type:

  • the index for std::vector
  • the key for std::map
  • FIRST_ELEMENT or LAST_ELEMENT for both vector and lists.
stl_element is not available for sets.

Accessing members of a map with string key

Suppose you have a map from strings to type T: std::map<string,T>, and you need to access a memeber mapped with key "hello". Since gdb will not call the string constructor from the c-string "hello", you have to call stl_to_str("hello") to create the key:

  print *stl_element(mymap, stl_to_str("hello"))

stl_element returns the pointer to the element. Such pointer can be either modified or just printed.

Dumping containers containing user-defined types

In order to dump containers that contain user-defined types, you have to provide a dumping function for those types.

To define the dumping function, use the DECLARE_STL_TO_COUT(type) macro to declare the heading of the function, then invoke stl_print() to print the individual attributes of your type. The parameter can be accessed as p:

#ifdef STL_DEBUG_ENABLE
DECLARE_STL_TO_COUT(MyClass::MyStruct)
{
    /* 'p' is the parameter */
    stl_print(p.a, false);
    stl_print(" ", false);
    stl_print(p.b, false);
}
#endif

Pass 'false' as the second argument of stl_print to avoid generating a new line.

See example.cpp for a complete example.

Printing a specific element of a container

To print a specific element, use stl_print combined with stl_element.

   call stl_print(*stl_element(myvec, 10))
   call stl_print(*stl_element(mymap, stl_to_str("hello")))

It will work for standard types; for used-defined types, see section above.

Keeping your code clean

In order to keep your code 'clean' (not messing it with debugging code), I suggest you to create a debug_support.h file where you put in there all the stl-debug related code (i.e. STL_DEBUG_REGISTER_xxx and DECLARE_STL_TO_COUT macros calls, etc.), so the only things you have to add to your main code, are the includes, and the STL_DEBUG_PRIVATE/PROTECTEDs. Include your debug_support.h file after all your class definitions.

Coming soon

Support for multimaps and multisets will follow.

Powered by Google Project Hosting