NAME

Devel::GDB::Reflect - Reflection API for GDB/C++

SYNOPSIS

use Devel::GDB;
use Devel::GDB::Reflect;

my $gdb = new Devel::GDB( -file => $foo );
my $reflector = new Devel::GDB::Reflect( $gdb );

print $gdb->get( "b foo.c:123" );
$gdb->print( "myVariable" );

DESCRIPTION

Devel::GDB::Reflect provides a reflection API for GDB/C++, which can be used to recursively print the contents of STL data structures (vector, set, map, etc.) within a GDB session. It is not limited to STL, however; you can write your own delegates for printing custom container types.

The module implements the functionality used by the gdb++ script, which serves as a wrapper around GDB. You should probably familiarize yourself with the basic functionality of this script first, before diving into the gory details presented here.

Global Variables

The following global variables control the behavior of the "print" method.

$Devel::GDB::Reflect::INDENT

The number of spaces to indent at each level of recursion. Defaults to 4.

$Devel::GDB::Reflect::MAX_DEPTH

The maximum recursion depth. Defaults to 5.

$Devel::GDB::Reflect::MAX_WIDTH

The maximum number of elements to show from a given container. Defaults to 10.

Methods

new

Create a new Devel::GDB::Reflect instance. Takes a single parameter, an instance of Devel::GDB.

When the constructor is invoked, it searches @INC for modules named Devel::GDB::Reflect::DelegateProvider::*, and recruits them as delegates. See "Delegates".

print

$reflector->print( "myVar" );

Given a variable or expression, recursively print the contents of the referenced container. Specifically, this checks the type of the variable, iterates over the delegates to determine the best one, then uses that delegate to print out the contents of the container.

The recursion is limited by $MAX_DEPTH, and for each container, the number of elements is limited by $MAX_WIDTH.

Delegates

Although this module is designed primarily for printing the contents of STL containers, it is fully extensible to support custom data types. The "print" method works by iterating over a set of delegates to determine how to print out a given variable.

A delegate is a hash consisting of:

priority

A numeric value used to disambiguate which delegate to use when there is more than one to choose from. For example, the fallback delegate (Devel::GDB::Reflect::DelegateProvider::Fallback) can print any data type, but has very low priority (-1000) to prevent it from being invoked unless no other delegate is available.

can_iterate

A boolean value, 1 if the delegate is used to print a container that should be iterated (such as a vector), or 0 if it is used to print a single value (such as a string). If can_iterate is true, then the delegate's factory must provide has_next and print_next; otherwise, it must provide print.

The string to print before and after the contents of the variable; defaults to "[" and "]" respectively.

The string to print between elements within the variable; defaults to ",". Only makes sense with can_iterate is true.

A boolean indicating whether or not to print a newline after printing the contents of the container. Typically this should be 1 (true) except for simple types.

factory

A sub taking a single parameter, $var (a C++ expression) and returning an object. This object is expected to contain either print (if can_iterate is false) or has_next and print_next:

print

Takes two parameters: $callback and $fh. Either prints the contents of $var directly to the file handle $fh, or invokes $callback to print $var recursively.

has_next

Like Java's Iterator.hasNext(), this function is called to determine whether or not there are any items remaining to print out.

Prints out the current element and advances the iterator (similarly again to Java's Iterator.next()).

Like print(), this function takes two parameters, $callback and $fh, and either prints directly to $fh or invokes $callback recursively.

Delegate Providers

A delegate provider is an object containing a method called get_delegates. This module searches for delegate providers by looking in @INC for modules by the name of Devel::GDB::Reflect::DelegateProvider::*.

The get_delegates method takes three parameters ($type, $var, $reflector): a type, a C++ expression, and an instance of Devel::GDB::Reflect. The $type is a hash, containing:

  • fullname: the full name of the type, including its namespace and template specialization, e.g. class std::vector<int,std::allocator<int> > *. This type should never be passed to GDB; use quotename instead.

  • shortname: the type name without the template or namespace, e.g. vector.

  • quotename: the full name, properly quoted to pass to GDB, e.g. class 'std::vector<int,std::allocator<int> >' *.

  • template: a ref to an array of types, denoting the template parameters (if any). In the above example, $type-{template}->[1]> would contain

    { fullname  => "std::allocator<int>",
      shortname => "allocator",
      quotename => "'std::allocator<int>'",
      template  => ... }

AUTHOR

Antal Novak afn@cpan.org