The libiberty library provides a set of functions and features that integrate and improve on functionality found in modern operating systems. Broadly speaking, such features can be divided into three groups:
- supplemental functions (functions that may be missing in some environments and operating systems);
- replacement functions (providing a uniform and easier to use interface for commonly used standard functions); and
- extensions (which provide additional functionality beyond standard functions).
GDB uses various features provided by the libiberty library, for instance the C++ demangler, the IEEE floating format support functions, the input options parser getopt, the obstack extension (see Obstacks in GDB), and other functions.
Note. libiberty is in part a reflection of the long ancestry of GCC, which predates such functionality being available elsewhere. There are now many other widely used free libraries offering this functionality in C, while C++ and its Standard Template Library also offer the same. Students of history are invited to consult the mailing list archives for the many debates on the subject of support libraries for GNU tools.
Obstacks in GDB
The obstack mechanism provides a convenient way to allocate and free chunks of memory. Each obstack is a pool of memory that is managed like a stack. Objects (of any nature, size and alignment) are allocated and freed in a LIFO fashion on an obstack (see libiberty's documentation for a more detailed explanation of obstacks).
The most noticeable use of obstacks in GDB is in object files. There is an obstack associated with each internal representation of an object file. Lots of things get allocated on these obstacks: dictionary entries, blocks, blockvectors, symbols, minimal symbols, types, vectors of fundamental types, class fields of types, object files section lists, object files section offset lists, line tables, symbol tables, partial symbol tables, string tables, symbol table private data, macros tables, debug information sections and entries, import and export lists (som), unwind information (hppa), dwarf2 location expressions data. Plus various strings such as directory names strings, debug format strings, names of types.
There are also obstacks associated with each architecture (part of struct gdbarch) and with the stack frame cache.
An essential and convenient property of all data on obstacks is that memory for it gets allocated (with obstack_alloc) at various times during a debugging session, but it is released all at once using the obstack_free function. The obstack_free function takes a pointer to where in the stack it must start the deletion from (much like the cleanup chains have a pointer to where to start the cleanups). Because of the stack like structure of the obstacks, this allows to free only a top portion of the obstack. There are a few instances in GDB where such thing happens. Calls to obstack_free are done after some local data is allocated to the obstack. Only the local data is deleted from the obstack. Of course this assumes that nothing between the obstack_alloc and the obstack_free allocates anything else on the same obstack. For this reason it is best and safest to use temporary obstacks.
Releasing the whole obstack is also not safe per se. It is safe only under the condition that we know the obstack's memory is no longer needed. In GDB we get rid of the obstacks only when we get rid of the whole objfile(s), for instance upon reading a new symbol file.
GDB provides a number of convenience functions and macros wrapping the standard obstack_alloc function. For example the function gdbarch_obstack_zalloc and macros GDBARCH_OBSTACK_CALLOC and GDBARCH_OBSTACK_ZALLOC are defined in gdbarch.h to simplify allocations on the GDB architecture obstack and the function frame_obstack_zalloc and macros FRAME_OBSTACK_CALLOC and FRAME_OBSTACK_ZALLOC are defined in frame.h to simplify allocations on the frame cache obstack.