@c Copyright (C) 2008--2021 Free Software Foundation, Inc.
@c Permission is granted to copy, distribute and/or modify this document
@c under the terms of the GNU Free Documentation License, Version 1.3 or
@c any later version published by the Free Software Foundation; with the
@c Invariant Sections being ``Free Software'' and ``Free Software Needs
@c Free Documentation'', with the Front-Cover Texts being ``A GNU Manual,''
@c and with the Back-Cover Texts as in (a) below.
@c 
@c (a) The FSF's Back-Cover Text is: ``You are free to copy and modify
@c this GNU Manual.  Buying copies from GNU Press supports the FSF in
@c developing GNU and promoting software freedom.''

@node Python
@section Extending @value{GDBN} using Python
@cindex python scripting
@cindex scripting with python

You can extend @value{GDBN} using the @uref{http://www.python.org/,
Python programming language}.  This feature is available only if
@value{GDBN} was configured using @option{--with-python}.
@value{GDBN} can be built against either Python 2 or Python 3; which
one you have depends on this configure-time option.

@cindex python directory
Python scripts used by @value{GDBN} should be installed in
@file{@var{data-directory}/python}, where @var{data-directory} is
the data directory as determined at @value{GDBN} startup (@pxref{Data Files}).
This directory, known as the @dfn{python directory},
is automatically added to the Python Search Path in order to allow
the Python interpreter to locate all scripts installed at this location.

Additionally, @value{GDBN} commands and convenience functions which
are written in Python and are located in the
@file{@var{data-directory}/python/gdb/command} or
@file{@var{data-directory}/python/gdb/function} directories are
automatically imported when @value{GDBN} starts.

@menu
* Python Commands::             Accessing Python from @value{GDBN}.
* Python API::                  Accessing @value{GDBN} from Python.
* Python Auto-loading::         Automatically loading Python code.
* Python modules::              Python modules provided by @value{GDBN}.
@end menu

@node Python Commands
@subsection Python Commands
@cindex python commands
@cindex commands to access python

@value{GDBN} provides two commands for accessing the Python interpreter,
and one related setting:

@table @code
@kindex python-interactive
@kindex pi
@item python-interactive @r{[}@var{command}@r{]}
@itemx pi @r{[}@var{command}@r{]}
Without an argument, the @code{python-interactive} command can be used
to start an interactive Python prompt.  To return to @value{GDBN},
type the @code{EOF} character (e.g., @kbd{Ctrl-D} on an empty prompt).

Alternatively, a single-line Python command can be given as an
argument and evaluated.  If the command is an expression, the result
will be printed; otherwise, nothing will be printed.  For example:

@smallexample
(@value{GDBP}) python-interactive 2 + 3
5
@end smallexample

@kindex python
@kindex py
@item python @r{[}@var{command}@r{]}
@itemx py @r{[}@var{command}@r{]}
The @code{python} command can be used to evaluate Python code.

If given an argument, the @code{python} command will evaluate the
argument as a Python command.  For example:

@smallexample
(@value{GDBP}) python print 23
23
@end smallexample

If you do not provide an argument to @code{python}, it will act as a
multi-line command, like @code{define}.  In this case, the Python
script is made up of subsequent command lines, given after the
@code{python} command.  This command list is terminated using a line
containing @code{end}.  For example:

@smallexample
(@value{GDBP}) python
>print 23
>end
23
@end smallexample

@kindex set python print-stack
@item set python print-stack
By default, @value{GDBN} will print only the message component of a
Python exception when an error occurs in a Python script.  This can be
controlled using @code{set python print-stack}: if @code{full}, then
full Python stack printing is enabled; if @code{none}, then Python stack
and message printing is disabled; if @code{message}, the default, only
the message component of the error is printed.

@kindex set python ignore-environment
@item set python ignore-environment @r{[}on@r{|}off@r{]}
By default this option is @samp{off}, and, when @value{GDBN}
initializes its internal Python interpreter, the Python interpreter
will check the environment for variables that will effect how it
behaves, for example @env{PYTHONHOME}, and
@env{PYTHONPATH}@footnote{See the ENVIRONMENT VARIABLES section of
@command{man 1 python} for a comprehensive list.}.

If this option is set to @samp{on} before Python is initialized then
Python will ignore all such environment variables.  As Python is
initialized early during @value{GDBN}'s startup process, then this
option must be placed into the early initialization file
(@pxref{Initialization Files}) to have the desired effect.

This option is equivalent to passing @option{-E} to the real
@command{python} executable.

@kindex set python dont-write-bytecode
@item set python dont-write-bytecode @r{[}auto@r{|}on@r{|}off@r{]}
When this option is @samp{off}, then, once @value{GDBN} has
initialized the Python interpreter, the interpreter will byte-compile
any Python modules that it imports and write the byte code to disk in
@file{.pyc} files.

If this option is set to @samp{on} before Python is initialized then
Python will no longer write the byte code to disk.  As Python is
initialized early during @value{GDBN}'s startup process, then this
option must be placed into the early initialization file
(@pxref{Initialization Files}) to have the desired effect.

By default this option is set to @samp{auto}, in this mode Python will
check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see
if it should write out byte-code or not.

This option is equivalent to passing @option{-B} to the real
@command{python} executable.
@end table

It is also possible to execute a Python script from the @value{GDBN}
interpreter:

@table @code
@item source @file{script-name}
The script name must end with @samp{.py} and @value{GDBN} must be configured
to recognize the script language based on filename extension using
the @code{script-extension} setting.  @xref{Extending GDB, ,Extending GDB}.
@end table

The following commands are intended to help debug @value{GDBN} itself:

@table @code
@kindex set debug py-breakpoint
@kindex show debug py-breakpoint
@item set debug py-breakpoint on@r{|}off
@itemx show debug py-breakpoint
When @samp{on}, @value{GDBN} prints debug messages related to the
Python breakpoint API.  This is @samp{off} by default.

@kindex set debug py-unwind
@kindex show debug py-unwind
@item set debug py-unwind on@r{|}off
@itemx show debug py-unwind
When @samp{on}, @value{GDBN} prints debug messages related to the
Python unwinder API.  This is @samp{off} by default.
@end table

@node Python API
@subsection Python API
@cindex python api
@cindex programming in python

You can get quick online help for @value{GDBN}'s Python API by issuing
the command @w{@kbd{python help (gdb)}}.

Functions and methods which have two or more optional arguments allow
them to be specified using keyword syntax.  This allows passing some
optional arguments while skipping others.  Example:
@w{@code{gdb.some_function ('foo', bar = 1, baz = 2)}}.

@menu
* Basic Python::                Basic Python Functions.
* Exception Handling::          How Python exceptions are translated.
* Values From Inferior::        Python representation of values.
* Types In Python::             Python representation of types.
* Pretty Printing API::         Pretty-printing values.
* Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
* Writing a Pretty-Printer::    Writing a Pretty-Printer.
* Type Printing API::		Pretty-printing types.
* Frame Filter API::            Filtering Frames.
* Frame Decorator API::         Decorating Frames.
* Writing a Frame Filter::      Writing a Frame Filter.
* Unwinding Frames in Python::  Writing frame unwinder.
* Xmethods In Python::          Adding and replacing methods of C++ classes.
* Xmethod API::                 Xmethod types.
* Writing an Xmethod::          Writing an xmethod.
* Inferiors In Python::         Python representation of inferiors (processes)
* Events In Python::            Listening for events from @value{GDBN}.
* Threads In Python::           Accessing inferior threads from Python.
* Recordings In Python::        Accessing recordings from Python.
* Commands In Python::          Implementing new commands in Python.
* Parameters In Python::        Adding new @value{GDBN} parameters.
* Functions In Python::         Writing new convenience functions.
* Progspaces In Python::        Program spaces.
* Objfiles In Python::          Object files.
* Frames In Python::            Accessing inferior stack frames from Python.
* Blocks In Python::            Accessing blocks from Python.
* Symbols In Python::           Python representation of symbols.
* Symbol Tables In Python::     Python representation of symbol tables.
* Line Tables In Python::       Python representation of line tables.
* Breakpoints In Python::       Manipulating breakpoints using Python.
* Finish Breakpoints in Python:: Setting Breakpoints on function return
                                using Python.
* Lazy Strings In Python::      Python representation of lazy strings.
* Architectures In Python::     Python representation of architectures.
* Registers In Python::         Python representation of registers.
* TUI Windows In Python::       Implementing new TUI windows.
@end menu

@node Basic Python
@subsubsection Basic Python

@cindex python stdout
@cindex python pagination
At startup, @value{GDBN} overrides Python's @code{sys.stdout} and
@code{sys.stderr} to print using @value{GDBN}'s output-paging streams.
A Python program which outputs to one of these streams may have its
output interrupted by the user (@pxref{Screen Size}).  In this
situation, a Python @code{KeyboardInterrupt} exception is thrown.

Some care must be taken when writing Python code to run in
@value{GDBN}.  Two things worth noting in particular:

@itemize @bullet
@item
@value{GDBN} install handlers for @code{SIGCHLD} and @code{SIGINT}.
Python code must not override these, or even change the options using
@code{sigaction}.  If your program changes the handling of these
signals, @value{GDBN} will most likely stop working correctly.  Note
that it is unfortunately common for GUI toolkits to install a
@code{SIGCHLD} handler.

@item
@value{GDBN} takes care to mark its internal file descriptors as
close-on-exec.  However, this cannot be done in a thread-safe way on
all platforms.  Your Python programs should be aware of this and
should both create new file descriptors with the close-on-exec flag
set and arrange to close unneeded file descriptors before starting a
child process.
@end itemize

@cindex python functions
@cindex python module
@cindex gdb module
@value{GDBN} introduces a new Python module, named @code{gdb}.  All
methods and classes added by @value{GDBN} are placed in this module.
@value{GDBN} automatically @code{import}s the @code{gdb} module for
use in all scripts evaluated by the @code{python} command.

Some types of the @code{gdb} module come with a textual representation
(accessible through the @code{repr} or @code{str} functions).  These are
offered for debugging purposes only, expect them to change over time.

@findex gdb.PYTHONDIR
@defvar gdb.PYTHONDIR
A string containing the python directory (@pxref{Python}).
@end defvar

@findex gdb.execute
@defun gdb.execute (command @r{[}, from_tty @r{[}, to_string@r{]]})
Evaluate @var{command}, a string, as a @value{GDBN} CLI command.
If a GDB exception happens while @var{command} runs, it is
translated as described in @ref{Exception Handling,,Exception Handling}.

The @var{from_tty} flag specifies whether @value{GDBN} ought to consider this
command as having originated from the user invoking it interactively.
It must be a boolean value.  If omitted, it defaults to @code{False}.

By default, any output produced by @var{command} is sent to
@value{GDBN}'s standard output (and to the log output if logging is
turned on).  If the @var{to_string} parameter is
@code{True}, then output will be collected by @code{gdb.execute} and
returned as a string.  The default is @code{False}, in which case the
return value is @code{None}.  If @var{to_string} is @code{True}, the
@value{GDBN} virtual terminal will be temporarily set to unlimited width
and height, and its pagination will be disabled; @pxref{Screen Size}.
@end defun

@findex gdb.breakpoints
@defun gdb.breakpoints ()
Return a sequence holding all of @value{GDBN}'s breakpoints.
@xref{Breakpoints In Python}, for more information.  In @value{GDBN}
version 7.11 and earlier, this function returned @code{None} if there
were no breakpoints.  This peculiarity was subsequently fixed, and now
@code{gdb.breakpoints} returns an empty sequence in this case.
@end defun

@defun gdb.rbreak (regex @r{[}, minsyms @r{[}, throttle, @r{[}, symtabs @r{]]]})
Return a Python list holding a collection of newly set
@code{gdb.Breakpoint} objects matching function names defined by the
@var{regex} pattern.  If the @var{minsyms} keyword is @code{True}, all
system functions (those not explicitly defined in the inferior) will
also be included in the match.  The @var{throttle} keyword takes an
integer that defines the maximum number of pattern matches for
functions matched by the @var{regex} pattern.  If the number of
matches exceeds the integer value of @var{throttle}, a
@code{RuntimeError} will be raised and no breakpoints will be created.
If @var{throttle} is not defined then there is no imposed limit on the
maximum number of matches and breakpoints to be created.  The
@var{symtabs} keyword takes a Python iterable that yields a collection
of @code{gdb.Symtab} objects and will restrict the search to those
functions only contained within the @code{gdb.Symtab} objects.
@end defun

@findex gdb.parameter
@defun gdb.parameter (parameter)
Return the value of a @value{GDBN} @var{parameter} given by its name,
a string; the parameter name string may contain spaces if the parameter has a
multi-part name.  For example, @samp{print object} is a valid
parameter name.

If the named parameter does not exist, this function throws a
@code{gdb.error} (@pxref{Exception Handling}).  Otherwise, the
parameter's value is converted to a Python value of the appropriate
type, and returned.
@end defun

@findex gdb.history
@defun gdb.history (number)
Return a value from @value{GDBN}'s value history (@pxref{Value
History}).  The @var{number} argument indicates which history element to return.
If @var{number} is negative, then @value{GDBN} will take its absolute value
and count backward from the last element (i.e., the most recent element) to
find the value to return.  If @var{number} is zero, then @value{GDBN} will
return the most recent element.  If the element specified by @var{number}
doesn't exist in the value history, a @code{gdb.error} exception will be
raised.

If no exception is raised, the return value is always an instance of
@code{gdb.Value} (@pxref{Values From Inferior}).
@end defun

@findex gdb.convenience_variable
@defun gdb.convenience_variable (name)
Return the value of the convenience variable (@pxref{Convenience
Vars}) named @var{name}.  @var{name} must be a string.  The name
should not include the @samp{$} that is used to mark a convenience
variable in an expression.  If the convenience variable does not
exist, then @code{None} is returned.
@end defun

@findex gdb.set_convenience_variable
@defun gdb.set_convenience_variable (name, value)
Set the value of the convenience variable (@pxref{Convenience Vars})
named @var{name}.  @var{name} must be a string.  The name should not
include the @samp{$} that is used to mark a convenience variable in an
expression.  If @var{value} is @code{None}, then the convenience
variable is removed.  Otherwise, if @var{value} is not a
@code{gdb.Value} (@pxref{Values From Inferior}), it is is converted
using the @code{gdb.Value} constructor.
@end defun

@findex gdb.parse_and_eval
@defun gdb.parse_and_eval (expression)
Parse @var{expression}, which must be a string, as an expression in
the current language, evaluate it, and return the result as a
@code{gdb.Value}.

This function can be useful when implementing a new command
(@pxref{Commands In Python}), as it provides a way to parse the
command's argument as an expression.  It is also useful simply to
compute values.
@end defun

@findex gdb.find_pc_line
@defun gdb.find_pc_line (pc)
Return the @code{gdb.Symtab_and_line} object corresponding to the
@var{pc} value.  @xref{Symbol Tables In Python}.  If an invalid
value of @var{pc} is passed as an argument, then the @code{symtab} and
@code{line} attributes of the returned @code{gdb.Symtab_and_line} object
will be @code{None} and 0 respectively.  This is identical to
@code{gdb.current_progspace().find_pc_line(pc)} and is included for
historical compatibility.
@end defun

@findex gdb.post_event
@defun gdb.post_event (event)
Put @var{event}, a callable object taking no arguments, into
@value{GDBN}'s internal event queue.  This callable will be invoked at
some later point, during @value{GDBN}'s event processing.  Events
posted using @code{post_event} will be run in the order in which they
were posted; however, there is no way to know when they will be
processed relative to other events inside @value{GDBN}.

@value{GDBN} is not thread-safe.  If your Python program uses multiple
threads, you must be careful to only call @value{GDBN}-specific
functions in the @value{GDBN} thread.  @code{post_event} ensures
this.  For example:

@smallexample
(@value{GDBP}) python
>import threading
>
>class Writer():
> def __init__(self, message):
>        self.message = message;
> def __call__(self):
>        gdb.write(self.message)
>
>class MyThread1 (threading.Thread):
> def run (self):
>        gdb.post_event(Writer("Hello "))
>
>class MyThread2 (threading.Thread):
> def run (self):
>        gdb.post_event(Writer("World\n"))
>
>MyThread1().start()
>MyThread2().start()
>end
(@value{GDBP}) Hello World
@end smallexample
@end defun

@findex gdb.write 
@defun gdb.write (string @r{[}, stream{]})
Print a string to @value{GDBN}'s paginated output stream.  The
optional @var{stream} determines the stream to print to.  The default
stream is @value{GDBN}'s standard output stream.  Possible stream
values are:

@table @code
@findex STDOUT
@findex gdb.STDOUT
@item gdb.STDOUT
@value{GDBN}'s standard output stream.

@findex STDERR
@findex gdb.STDERR
@item gdb.STDERR
@value{GDBN}'s standard error stream.

@findex STDLOG
@findex gdb.STDLOG
@item gdb.STDLOG
@value{GDBN}'s log stream (@pxref{Logging Output}).
@end table

Writing to @code{sys.stdout} or @code{sys.stderr} will automatically
call this function and will automatically direct the output to the
relevant stream.
@end defun

@findex gdb.flush
@defun gdb.flush ()
Flush the buffer of a @value{GDBN} paginated stream so that the
contents are displayed immediately.  @value{GDBN} will flush the
contents of a stream automatically when it encounters a newline in the
buffer.  The optional @var{stream} determines the stream to flush.  The
default stream is @value{GDBN}'s standard output stream.  Possible
stream values are: 

@table @code
@findex STDOUT
@findex gdb.STDOUT
@item gdb.STDOUT
@value{GDBN}'s standard output stream.

@findex STDERR
@findex gdb.STDERR
@item gdb.STDERR
@value{GDBN}'s standard error stream.

@findex STDLOG
@findex gdb.STDLOG
@item gdb.STDLOG
@value{GDBN}'s log stream (@pxref{Logging Output}).

@end table

Flushing @code{sys.stdout} or @code{sys.stderr} will automatically
call this function for the relevant stream.
@end defun

@findex gdb.target_charset
@defun gdb.target_charset ()
Return the name of the current target character set (@pxref{Character
Sets}).  This differs from @code{gdb.parameter('target-charset')} in
that @samp{auto} is never returned.
@end defun

@findex gdb.target_wide_charset
@defun gdb.target_wide_charset ()
Return the name of the current target wide character set
(@pxref{Character Sets}).  This differs from
@code{gdb.parameter('target-wide-charset')} in that @samp{auto} is
never returned.
@end defun

@findex gdb.solib_name
@defun gdb.solib_name (address)
Return the name of the shared library holding the given @var{address}
as a string, or @code{None}.  This is identical to
@code{gdb.current_progspace().solib_name(address)} and is included for
historical compatibility.
@end defun

@findex gdb.decode_line 
@defun gdb.decode_line (@r{[}expression@r{]})
Return locations of the line specified by @var{expression}, or of the
current line if no argument was given.  This function returns a Python
tuple containing two elements.  The first element contains a string
holding any unparsed section of @var{expression} (or @code{None} if
the expression has been fully parsed).  The second element contains
either @code{None} or another tuple that contains all the locations
that match the expression represented as @code{gdb.Symtab_and_line}
objects (@pxref{Symbol Tables In Python}).  If @var{expression} is
provided, it is decoded the way that @value{GDBN}'s inbuilt
@code{break} or @code{edit} commands do (@pxref{Specify Location}).
@end defun

@defun gdb.prompt_hook (current_prompt)
@anchor{prompt_hook}

If @var{prompt_hook} is callable, @value{GDBN} will call the method
assigned to this operation before a prompt is displayed by
@value{GDBN}.

The parameter @code{current_prompt} contains the current @value{GDBN} 
prompt.  This method must return a Python string, or @code{None}.  If
a string is returned, the @value{GDBN} prompt will be set to that
string.  If @code{None} is returned, @value{GDBN} will continue to use
the current prompt.

Some prompts cannot be substituted in @value{GDBN}.  Secondary prompts
such as those used by readline for command input, and annotation
related prompts are prohibited from being changed.
@end defun

@node Exception Handling
@subsubsection Exception Handling
@cindex python exceptions
@cindex exceptions, python

When executing the @code{python} command, Python exceptions
uncaught within the Python code are translated to calls to
@value{GDBN} error-reporting mechanism.  If the command that called
@code{python} does not handle the error, @value{GDBN} will
terminate it and print an error message containing the Python
exception name, the associated value, and the Python call stack
backtrace at the point where the exception was raised.  Example:

@smallexample
(@value{GDBP}) python print foo
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'foo' is not defined
@end smallexample

@value{GDBN} errors that happen in @value{GDBN} commands invoked by
Python code are converted to Python exceptions.  The type of the
Python exception depends on the error.

@ftable @code
@item gdb.error
This is the base class for most exceptions generated by @value{GDBN}.
It is derived from @code{RuntimeError}, for compatibility with earlier
versions of @value{GDBN}.

If an error occurring in @value{GDBN} does not fit into some more
specific category, then the generated exception will have this type.

@item gdb.MemoryError
This is a subclass of @code{gdb.error} which is thrown when an
operation tried to access invalid memory in the inferior.

@item KeyboardInterrupt
User interrupt (via @kbd{C-c} or by typing @kbd{q} at a pagination
prompt) is translated to a Python @code{KeyboardInterrupt} exception.
@end ftable

In all cases, your exception handler will see the @value{GDBN} error
message as its value and the Python call stack backtrace at the Python
statement closest to where the @value{GDBN} error occured as the
traceback.


When implementing @value{GDBN} commands in Python via
@code{gdb.Command}, or functions via @code{gdb.Function}, it is useful
to be able to throw an exception that doesn't cause a traceback to be
printed.  For example, the user may have invoked the command
incorrectly.  @value{GDBN} provides a special exception class that can
be used for this purpose.

@ftable @code
@item gdb.GdbError
When thrown from a command or function, this exception will cause the
command or function to fail, but the Python stack will not be
displayed.  @value{GDBN} does not throw this exception itself, but
rather recognizes it when thrown from user Python code.  Example:

@smallexample
(gdb) python
>class HelloWorld (gdb.Command):
>  """Greet the whole world."""
>  def __init__ (self):
>    super (HelloWorld, self).__init__ ("hello-world", gdb.COMMAND_USER)
>  def invoke (self, args, from_tty):
>    argv = gdb.string_to_argv (args)
>    if len (argv) != 0:
>      raise gdb.GdbError ("hello-world takes no arguments")
>    print ("Hello, World!")
>HelloWorld ()
>end
(gdb) hello-world 42
hello-world takes no arguments
@end smallexample
@end ftable

@node Values From Inferior
@subsubsection Values From Inferior
@cindex values from inferior, with Python
@cindex python, working with values from inferior

@cindex @code{gdb.Value}
@value{GDBN} provides values it obtains from the inferior program in
an object of type @code{gdb.Value}.  @value{GDBN} uses this object
for its internal bookkeeping of the inferior's values, and for
fetching values when necessary.

Inferior values that are simple scalars can be used directly in
Python expressions that are valid for the value's data type.  Here's
an example for an integer or floating-point value @code{some_val}:

@smallexample
bar = some_val + 2
@end smallexample

@noindent
As result of this, @code{bar} will also be a @code{gdb.Value} object
whose values are of the same type as those of @code{some_val}.  Valid
Python operations can also be performed on @code{gdb.Value} objects
representing a @code{struct} or @code{class} object.  For such cases,
the overloaded operator (if present), is used to perform the operation.
For example, if @code{val1} and @code{val2} are @code{gdb.Value} objects
representing instances of a @code{class} which overloads the @code{+}
operator, then one can use the @code{+} operator in their Python script
as follows:

@smallexample
val3 = val1 + val2
@end smallexample

@noindent
The result of the operation @code{val3} is also a @code{gdb.Value}
object corresponding to the value returned by the overloaded @code{+}
operator.  In general, overloaded operators are invoked for the
following operations: @code{+} (binary addition), @code{-} (binary
subtraction), @code{*} (multiplication), @code{/}, @code{%}, @code{<<},
@code{>>}, @code{|}, @code{&}, @code{^}.

Inferior values that are structures or instances of some class can
be accessed using the Python @dfn{dictionary syntax}.  For example, if
@code{some_val} is a @code{gdb.Value} instance holding a structure, you
can access its @code{foo} element with:

@smallexample
bar = some_val['foo']
@end smallexample

@cindex getting structure elements using gdb.Field objects as subscripts
Again, @code{bar} will also be a @code{gdb.Value} object.  Structure
elements can also be accessed by using @code{gdb.Field} objects as
subscripts (@pxref{Types In Python}, for more information on
@code{gdb.Field} objects).  For example, if @code{foo_field} is a
@code{gdb.Field} object corresponding to element @code{foo} of the above
structure, then @code{bar} can also be accessed as follows:

@smallexample
bar = some_val[foo_field]
@end smallexample

A @code{gdb.Value} that represents a function can be executed via
inferior function call.  Any arguments provided to the call must match
the function's prototype, and must be provided in the order specified
by that prototype.

For example, @code{some_val} is a @code{gdb.Value} instance
representing a function that takes two integers as arguments.  To
execute this function, call it like so:

@smallexample
result = some_val (10,20)
@end smallexample

Any values returned from a function call will be stored as a
@code{gdb.Value}.

The following attributes are provided:

@defvar Value.address
If this object is addressable, this read-only attribute holds a
@code{gdb.Value} object representing the address.  Otherwise,
this attribute holds @code{None}.
@end defvar

@cindex optimized out value in Python
@defvar Value.is_optimized_out
This read-only boolean attribute is true if the compiler optimized out
this value, thus it is not available for fetching from the inferior.
@end defvar

@defvar Value.type
The type of this @code{gdb.Value}.  The value of this attribute is a
@code{gdb.Type} object (@pxref{Types In Python}).
@end defvar

@defvar Value.dynamic_type
The dynamic type of this @code{gdb.Value}.  This uses the object's
virtual table and the C@t{++} run-time type information
(@acronym{RTTI}) to determine the dynamic type of the value.  If this
value is of class type, it will return the class in which the value is
embedded, if any.  If this value is of pointer or reference to a class
type, it will compute the dynamic type of the referenced object, and
return a pointer or reference to that type, respectively.  In all
other cases, it will return the value's static type.

Note that this feature will only work when debugging a C@t{++} program
that includes @acronym{RTTI} for the object in question.  Otherwise,
it will just return the static type of the value as in @kbd{ptype foo}
(@pxref{Symbols, ptype}).
@end defvar

@defvar Value.is_lazy
The value of this read-only boolean attribute is @code{True} if this
@code{gdb.Value} has not yet been fetched from the inferior.  
@value{GDBN} does not fetch values until necessary, for efficiency.  
For example:

@smallexample
myval = gdb.parse_and_eval ('somevar')
@end smallexample

The value of @code{somevar} is not fetched at this time.  It will be 
fetched when the value is needed, or when the @code{fetch_lazy}
method is invoked.  
@end defvar

The following methods are provided:

@defun Value.__init__ (@var{val})
Many Python values can be converted directly to a @code{gdb.Value} via
this object initializer.  Specifically:

@table @asis
@item Python boolean
A Python boolean is converted to the boolean type from the current
language.

@item Python integer
A Python integer is converted to the C @code{long} type for the
current architecture.

@item Python long
A Python long is converted to the C @code{long long} type for the
current architecture.

@item Python float
A Python float is converted to the C @code{double} type for the
current architecture.

@item Python string
A Python string is converted to a target string in the current target
language using the current target encoding.
If a character cannot be represented in the current target encoding,
then an exception is thrown.

@item @code{gdb.Value}
If @code{val} is a @code{gdb.Value}, then a copy of the value is made.

@item @code{gdb.LazyString}
If @code{val} is a @code{gdb.LazyString} (@pxref{Lazy Strings In
Python}), then the lazy string's @code{value} method is called, and
its result is used.
@end table
@end defun

@defun Value.__init__ (@var{val}, @var{type})
This second form of the @code{gdb.Value} constructor returns a
@code{gdb.Value} of type @var{type} where the value contents are taken
from the Python buffer object specified by @var{val}.  The number of
bytes in the Python buffer object must be greater than or equal to the
size of @var{type}.
@end defun

@defun Value.cast (type)
Return a new instance of @code{gdb.Value} that is the result of
casting this instance to the type described by @var{type}, which must
be a @code{gdb.Type} object.  If the cast cannot be performed for some
reason, this method throws an exception.
@end defun

@defun Value.dereference ()
For pointer data types, this method returns a new @code{gdb.Value} object
whose contents is the object pointed to by the pointer.  For example, if
@code{foo} is a C pointer to an @code{int}, declared in your C program as

@smallexample
int *foo;
@end smallexample

@noindent
then you can use the corresponding @code{gdb.Value} to access what
@code{foo} points to like this:

@smallexample
bar = foo.dereference ()
@end smallexample

The result @code{bar} will be a @code{gdb.Value} object holding the
value pointed to by @code{foo}.

A similar function @code{Value.referenced_value} exists which also
returns @code{gdb.Value} objects corresponding to the values pointed to
by pointer values (and additionally, values referenced by reference
values).  However, the behavior of @code{Value.dereference}
differs from @code{Value.referenced_value} by the fact that the
behavior of @code{Value.dereference} is identical to applying the C
unary operator @code{*} on a given value.  For example, consider a
reference to a pointer @code{ptrref}, declared in your C@t{++} program
as

@smallexample
typedef int *intptr;
...
int val = 10;
intptr ptr = &val;
intptr &ptrref = ptr;
@end smallexample

Though @code{ptrref} is a reference value, one can apply the method
@code{Value.dereference} to the @code{gdb.Value} object corresponding
to it and obtain a @code{gdb.Value} which is identical to that
corresponding to @code{val}.  However, if you apply the method
@code{Value.referenced_value}, the result would be a @code{gdb.Value}
object identical to that corresponding to @code{ptr}.

@smallexample
py_ptrref = gdb.parse_and_eval ("ptrref")
py_val = py_ptrref.dereference ()
py_ptr = py_ptrref.referenced_value ()
@end smallexample

The @code{gdb.Value} object @code{py_val} is identical to that
corresponding to @code{val}, and @code{py_ptr} is identical to that
corresponding to @code{ptr}.  In general, @code{Value.dereference} can
be applied whenever the C unary operator @code{*} can be applied
to the corresponding C value.  For those cases where applying both
@code{Value.dereference} and @code{Value.referenced_value} is allowed,
the results obtained need not be identical (as we have seen in the above
example).  The results are however identical when applied on
@code{gdb.Value} objects corresponding to pointers (@code{gdb.Value}
objects with type code @code{TYPE_CODE_PTR}) in a C/C@t{++} program.
@end defun

@defun Value.referenced_value ()
For pointer or reference data types, this method returns a new
@code{gdb.Value} object corresponding to the value referenced by the
pointer/reference value.  For pointer data types,
@code{Value.dereference} and @code{Value.referenced_value} produce
identical results.  The difference between these methods is that
@code{Value.dereference} cannot get the values referenced by reference
values.  For example, consider a reference to an @code{int}, declared
in your C@t{++} program as

@smallexample
int val = 10;
int &ref = val;
@end smallexample

@noindent
then applying @code{Value.dereference} to the @code{gdb.Value} object
corresponding to @code{ref} will result in an error, while applying
@code{Value.referenced_value} will result in a @code{gdb.Value} object
identical to that corresponding to @code{val}.

@smallexample
py_ref = gdb.parse_and_eval ("ref")
er_ref = py_ref.dereference ()       # Results in error
py_val = py_ref.referenced_value ()  # Returns the referenced value
@end smallexample

The @code{gdb.Value} object @code{py_val} is identical to that
corresponding to @code{val}.
@end defun

@defun Value.reference_value ()
Return a @code{gdb.Value} object which is a reference to the value
encapsulated by this instance.
@end defun

@defun Value.const_value ()
Return a @code{gdb.Value} object which is a @code{const} version of the
value encapsulated by this instance.
@end defun

@defun Value.dynamic_cast (type)
Like @code{Value.cast}, but works as if the C@t{++} @code{dynamic_cast}
operator were used.  Consult a C@t{++} reference for details.
@end defun

@defun Value.reinterpret_cast (type)
Like @code{Value.cast}, but works as if the C@t{++} @code{reinterpret_cast}
operator were used.  Consult a C@t{++} reference for details.
@end defun

@defun Value.format_string (...)
Convert a @code{gdb.Value} to a string, similarly to what the @code{print}
command does.  Invoked with no arguments, this is equivalent to calling
the @code{str} function on the @code{gdb.Value}.  The representation of
the same value may change across different versions of @value{GDBN}, so
you shouldn't, for instance, parse the strings returned by this method.

All the arguments are keyword only.  If an argument is not specified, the
current global default setting is used.

@table @code
@item raw
@code{True} if pretty-printers (@pxref{Pretty Printing}) should not be
used to format the value.  @code{False} if enabled pretty-printers
matching the type represented by the @code{gdb.Value} should be used to
format it.

@item pretty_arrays
@code{True} if arrays should be pretty printed to be more convenient to
read, @code{False} if they shouldn't (see @code{set print array} in
@ref{Print Settings}).

@item pretty_structs
@code{True} if structs should be pretty printed to be more convenient to
read, @code{False} if they shouldn't (see @code{set print pretty} in
@ref{Print Settings}).

@item array_indexes
@code{True} if array indexes should be included in the string
representation of arrays, @code{False} if they shouldn't (see @code{set
print array-indexes} in @ref{Print Settings}).

@item symbols
@code{True} if the string representation of a pointer should include the
corresponding symbol name (if one exists), @code{False} if it shouldn't
(see @code{set print symbol} in @ref{Print Settings}).

@item unions
@code{True} if unions which are contained in other structures or unions
should be expanded, @code{False} if they shouldn't (see @code{set print
union} in @ref{Print Settings}).

@item address
@code{True} if the string representation of a pointer should include the
address, @code{False} if it shouldn't (see @code{set print address} in
@ref{Print Settings}).

@item deref_refs
@code{True} if C@t{++} references should be resolved to the value they
refer to, @code{False} (the default) if they shouldn't.  Note that, unlike
for the @code{print} command, references are not automatically expanded
when using the @code{format_string} method or the @code{str}
function.  There is no global @code{print} setting to change the default
behaviour.

@item actual_objects
@code{True} if the representation of a pointer to an object should
identify the @emph{actual} (derived) type of the object rather than the
@emph{declared} type, using the virtual function table.  @code{False} if
the @emph{declared} type should be used.  (See @code{set print object} in
@ref{Print Settings}).

@item static_members
@code{True} if static members should be included in the string
representation of a C@t{++} object, @code{False} if they shouldn't (see
@code{set print static-members} in @ref{Print Settings}).

@item max_elements
Number of array elements to print, or @code{0} to print an unlimited
number of elements (see @code{set print elements} in @ref{Print
Settings}).

@item max_depth
The maximum depth to print for nested structs and unions, or @code{-1}
to print an unlimited number of elements (see @code{set print
max-depth} in @ref{Print Settings}).

@item repeat_threshold
Set the threshold for suppressing display of repeated array elements, or
@code{0} to represent all elements, even if repeated.  (See @code{set
print repeats} in @ref{Print Settings}).

@item format
A string containing a single character representing the format to use for
the returned string.  For instance, @code{'x'} is equivalent to using the
@value{GDBN} command @code{print} with the @code{/x} option and formats
the value as a hexadecimal number.
@end table
@end defun

@defun Value.string (@r{[}encoding@r{[}, errors@r{[}, length@r{]]]})
If this @code{gdb.Value} represents a string, then this method
converts the contents to a Python string.  Otherwise, this method will
throw an exception.

Values are interpreted as strings according to the rules of the
current language.  If the optional length argument is given, the
string will be converted to that length, and will include any embedded
zeroes that the string may contain.  Otherwise, for languages
where the string is zero-terminated, the entire string will be
converted.

For example, in C-like languages, a value is a string if it is a pointer
to or an array of characters or ints of type @code{wchar_t}, @code{char16_t},
or @code{char32_t}.

If the optional @var{encoding} argument is given, it must be a string
naming the encoding of the string in the @code{gdb.Value}, such as
@code{"ascii"}, @code{"iso-8859-6"} or @code{"utf-8"}.  It accepts
the same encodings as the corresponding argument to Python's
@code{string.decode} method, and the Python codec machinery will be used
to convert the string.  If @var{encoding} is not given, or if
@var{encoding} is the empty string, then either the @code{target-charset}
(@pxref{Character Sets}) will be used, or a language-specific encoding
will be used, if the current language is able to supply one.

The optional @var{errors} argument is the same as the corresponding
argument to Python's @code{string.decode} method.

If the optional @var{length} argument is given, the string will be
fetched and converted to the given length.
@end defun

@defun Value.lazy_string (@r{[}encoding @r{[}, length@r{]]})
If this @code{gdb.Value} represents a string, then this method
converts the contents to a @code{gdb.LazyString} (@pxref{Lazy Strings
In Python}).  Otherwise, this method will throw an exception.

If the optional @var{encoding} argument is given, it must be a string
naming the encoding of the @code{gdb.LazyString}.  Some examples are:
@samp{ascii}, @samp{iso-8859-6} or @samp{utf-8}.  If the
@var{encoding} argument is an encoding that @value{GDBN} does
recognize, @value{GDBN} will raise an error.

When a lazy string is printed, the @value{GDBN} encoding machinery is
used to convert the string during printing.  If the optional
@var{encoding} argument is not provided, or is an empty string,
@value{GDBN} will automatically select the encoding most suitable for
the string type.  For further information on encoding in @value{GDBN}
please see @ref{Character Sets}.

If the optional @var{length} argument is given, the string will be
fetched and encoded to the length of characters specified.  If
the @var{length} argument is not provided, the string will be fetched
and encoded until a null of appropriate width is found.
@end defun

@defun Value.fetch_lazy ()
If the @code{gdb.Value} object is currently a lazy value 
(@code{gdb.Value.is_lazy} is @code{True}), then the value is
fetched from the inferior.  Any errors that occur in the process
will produce a Python exception.

If the @code{gdb.Value} object is not a lazy value, this method
has no effect.

This method does not return a value.
@end defun


@node Types In Python
@subsubsection Types In Python
@cindex types in Python
@cindex Python, working with types

@tindex gdb.Type
@value{GDBN} represents types from the inferior using the class
@code{gdb.Type}.

The following type-related functions are available in the @code{gdb}
module:

@findex gdb.lookup_type
@defun gdb.lookup_type (name @r{[}, block@r{]})
This function looks up a type by its @var{name}, which must be a string.

If @var{block} is given, then @var{name} is looked up in that scope.
Otherwise, it is searched for globally.

Ordinarily, this function will return an instance of @code{gdb.Type}.
If the named type cannot be found, it will throw an exception.
@end defun

If the type is a structure or class type, or an enum type, the fields
of that type can be accessed using the Python @dfn{dictionary syntax}.
For example, if @code{some_type} is a @code{gdb.Type} instance holding
a structure type, you can access its @code{foo} field with:

@smallexample
bar = some_type['foo']
@end smallexample

@code{bar} will be a @code{gdb.Field} object; see below under the
description of the @code{Type.fields} method for a description of the
@code{gdb.Field} class.

An instance of @code{Type} has the following attributes:

@defvar Type.alignof
The alignment of this type, in bytes.  Type alignment comes from the
debugging information; if it was not specified, then @value{GDBN} will
use the relevant ABI to try to determine the alignment.  In some
cases, even this is not possible, and zero will be returned.
@end defvar

@defvar Type.code
The type code for this type.  The type code will be one of the
@code{TYPE_CODE_} constants defined below.
@end defvar

@defvar Type.dynamic
A boolean indicating whether this type is dynamic.  In some
situations, such as Rust @code{enum} types or Ada variant records, the
concrete type of a value may vary depending on its contents.  That is,
the declared type of a variable, or the type returned by
@code{gdb.lookup_type} may be dynamic; while the type of the
variable's value will be a concrete instance of that dynamic type.

For example, consider this code:
@smallexample
int n;
int array[n];
@end smallexample

Here, at least conceptually (whether your compiler actually does this
is a separate issue), examining @w{@code{gdb.lookup_symbol("array", ...).type}}
could yield a @code{gdb.Type} which reports a size of @code{None}.
This is the dynamic type.

However, examining @code{gdb.parse_and_eval("array").type} would yield
a concrete type, whose length would be known.
@end defvar

@defvar Type.name
The name of this type.  If this type has no name, then @code{None}
is returned.
@end defvar

@defvar Type.sizeof
The size of this type, in target @code{char} units.  Usually, a
target's @code{char} type will be an 8-bit byte.  However, on some
unusual platforms, this type may have a different size.  A dynamic
type may not have a fixed size; in this case, this attribute's value
will be @code{None}.
@end defvar

@defvar Type.tag
The tag name for this type.  The tag name is the name after
@code{struct}, @code{union}, or @code{enum} in C and C@t{++}; not all
languages have this concept.  If this type has no tag name, then
@code{None} is returned.
@end defvar

@defvar Type.objfile
The @code{gdb.Objfile} that this type was defined in, or @code{None} if
there is no associated objfile.
@end defvar

The following methods are provided:

@defun Type.fields ()

Return the fields of this type.  The behavior depends on the type code:

@itemize @bullet

@item
For structure and union types, this method returns the fields.

@item
Range types have two fields, the minimum and maximum values.

@item
Enum types have one field per enum constant.

@item
Function and method types have one field per parameter.  The base types of
C@t{++} classes are also represented as fields.

@item
Array types have one field representing the array's range.

@item
If the type does not fit into one of these categories, a @code{TypeError}
is raised.

@end itemize

Each field is a @code{gdb.Field} object, with some pre-defined attributes:
@table @code
@item bitpos
This attribute is not available for @code{enum} or @code{static}
(as in C@t{++}) fields.  The value is the position, counting
in bits, from the start of the containing type.  Note that, in a
dynamic type, the position of a field may not be constant.  In this
case, the value will be @code{None}.  Also, a dynamic type may have
fields that do not appear in a corresponding concrete type.

@item enumval
This attribute is only available for @code{enum} fields, and its value
is the enumeration member's integer representation.

@item name
The name of the field, or @code{None} for anonymous fields.

@item artificial
This is @code{True} if the field is artificial, usually meaning that
it was provided by the compiler and not the user.  This attribute is
always provided, and is @code{False} if the field is not artificial.

@item is_base_class
This is @code{True} if the field represents a base class of a C@t{++}
structure.  This attribute is always provided, and is @code{False}
if the field is not a base class of the type that is the argument of
@code{fields}, or if that type was not a C@t{++} class.

@item bitsize
If the field is packed, or is a bitfield, then this will have a
non-zero value, which is the size of the field in bits.  Otherwise,
this will be zero; in this case the field's size is given by its type.

@item type
The type of the field.  This is usually an instance of @code{Type},
but it can be @code{None} in some situations.

@item parent_type
The type which contains this field.  This is an instance of
@code{gdb.Type}.
@end table
@end defun

@defun Type.array (@var{n1} @r{[}, @var{n2}@r{]})
Return a new @code{gdb.Type} object which represents an array of this
type.  If one argument is given, it is the inclusive upper bound of
the array; in this case the lower bound is zero.  If two arguments are
given, the first argument is the lower bound of the array, and the
second argument is the upper bound of the array.  An array's length
must not be negative, but the bounds can be.
@end defun

@defun Type.vector (@var{n1} @r{[}, @var{n2}@r{]})
Return a new @code{gdb.Type} object which represents a vector of this
type.  If one argument is given, it is the inclusive upper bound of
the vector; in this case the lower bound is zero.  If two arguments are
given, the first argument is the lower bound of the vector, and the
second argument is the upper bound of the vector.  A vector's length
must not be negative, but the bounds can be.

The difference between an @code{array} and a @code{vector} is that
arrays behave like in C: when used in expressions they decay to a pointer
to the first element whereas vectors are treated as first class values.
@end defun

@defun Type.const ()
Return a new @code{gdb.Type} object which represents a
@code{const}-qualified variant of this type.
@end defun

@defun Type.volatile ()
Return a new @code{gdb.Type} object which represents a
@code{volatile}-qualified variant of this type.
@end defun

@defun Type.unqualified ()
Return a new @code{gdb.Type} object which represents an unqualified
variant of this type.  That is, the result is neither @code{const} nor
@code{volatile}.
@end defun

@defun Type.range ()
Return a Python @code{Tuple} object that contains two elements: the
low bound of the argument type and the high bound of that type.  If
the type does not have a range, @value{GDBN} will raise a
@code{gdb.error} exception (@pxref{Exception Handling}).
@end defun

@defun Type.reference ()
Return a new @code{gdb.Type} object which represents a reference to this
type.
@end defun

@defun Type.pointer ()
Return a new @code{gdb.Type} object which represents a pointer to this
type.
@end defun

@defun Type.strip_typedefs ()
Return a new @code{gdb.Type} that represents the real type,
after removing all layers of typedefs.
@end defun

@defun Type.target ()
Return a new @code{gdb.Type} object which represents the target type
of this type.

For a pointer type, the target type is the type of the pointed-to
object.  For an array type (meaning C-like arrays), the target type is
the type of the elements of the array.  For a function or method type,
the target type is the type of the return value.  For a complex type,
the target type is the type of the elements.  For a typedef, the
target type is the aliased type.

If the type does not have a target, this method will throw an
exception.
@end defun

@defun Type.template_argument (n @r{[}, block@r{]})
If this @code{gdb.Type} is an instantiation of a template, this will
return a new @code{gdb.Value} or @code{gdb.Type} which represents the
value of the @var{n}th template argument (indexed starting at 0).

If this @code{gdb.Type} is not a template type, or if the type has fewer
than @var{n} template arguments, this will throw an exception.
Ordinarily, only C@t{++} code will have template types.

If @var{block} is given, then @var{name} is looked up in that scope.
Otherwise, it is searched for globally.
@end defun

@defun Type.optimized_out ()
Return @code{gdb.Value} instance of this type whose value is optimized
out.  This allows a frame decorator to indicate that the value of an
argument or a local variable is not known.
@end defun

Each type has a code, which indicates what category this type falls
into.  The available type categories are represented by constants
defined in the @code{gdb} module:

@vtable @code
@vindex TYPE_CODE_PTR
@item gdb.TYPE_CODE_PTR
The type is a pointer.

@vindex TYPE_CODE_ARRAY
@item gdb.TYPE_CODE_ARRAY
The type is an array.

@vindex TYPE_CODE_STRUCT
@item gdb.TYPE_CODE_STRUCT
The type is a structure.

@vindex TYPE_CODE_UNION
@item gdb.TYPE_CODE_UNION
The type is a union.

@vindex TYPE_CODE_ENUM
@item gdb.TYPE_CODE_ENUM
The type is an enum.

@vindex TYPE_CODE_FLAGS
@item gdb.TYPE_CODE_FLAGS
A bit flags type, used for things such as status registers.

@vindex TYPE_CODE_FUNC
@item gdb.TYPE_CODE_FUNC
The type is a function.

@vindex TYPE_CODE_INT
@item gdb.TYPE_CODE_INT
The type is an integer type.

@vindex TYPE_CODE_FLT
@item gdb.TYPE_CODE_FLT
A floating point type.

@vindex TYPE_CODE_VOID
@item gdb.TYPE_CODE_VOID
The special type @code{void}.

@vindex TYPE_CODE_SET
@item gdb.TYPE_CODE_SET
A Pascal set type.

@vindex TYPE_CODE_RANGE
@item gdb.TYPE_CODE_RANGE
A range type, that is, an integer type with bounds.

@vindex TYPE_CODE_STRING
@item gdb.TYPE_CODE_STRING
A string type.  Note that this is only used for certain languages with
language-defined string types; C strings are not represented this way.

@vindex TYPE_CODE_BITSTRING
@item gdb.TYPE_CODE_BITSTRING
A string of bits.  It is deprecated.

@vindex TYPE_CODE_ERROR
@item gdb.TYPE_CODE_ERROR
An unknown or erroneous type.

@vindex TYPE_CODE_METHOD
@item gdb.TYPE_CODE_METHOD
A method type, as found in C@t{++}.

@vindex TYPE_CODE_METHODPTR
@item gdb.TYPE_CODE_METHODPTR
A pointer-to-member-function.

@vindex TYPE_CODE_MEMBERPTR
@item gdb.TYPE_CODE_MEMBERPTR
A pointer-to-member.

@vindex TYPE_CODE_REF
@item gdb.TYPE_CODE_REF
A reference type.

@vindex TYPE_CODE_RVALUE_REF
@item gdb.TYPE_CODE_RVALUE_REF
A C@t{++}11 rvalue reference type.

@vindex TYPE_CODE_CHAR
@item gdb.TYPE_CODE_CHAR
A character type.

@vindex TYPE_CODE_BOOL
@item gdb.TYPE_CODE_BOOL
A boolean type.

@vindex TYPE_CODE_COMPLEX
@item gdb.TYPE_CODE_COMPLEX
A complex float type.

@vindex TYPE_CODE_TYPEDEF
@item gdb.TYPE_CODE_TYPEDEF
A typedef to some other type.

@vindex TYPE_CODE_NAMESPACE
@item gdb.TYPE_CODE_NAMESPACE
A C@t{++} namespace.

@vindex TYPE_CODE_DECFLOAT
@item gdb.TYPE_CODE_DECFLOAT
A decimal floating point type.

@vindex TYPE_CODE_INTERNAL_FUNCTION
@item gdb.TYPE_CODE_INTERNAL_FUNCTION
A function internal to @value{GDBN}.  This is the type used to represent
convenience functions.
@end vtable

Further support for types is provided in the @code{gdb.types}
Python module (@pxref{gdb.types}).

@node Pretty Printing API
@subsubsection Pretty Printing API
@cindex python pretty printing api

A pretty-printer is just an object that holds a value and implements a
specific interface, defined here.  An example output is provided
(@pxref{Pretty Printing}).

@defun pretty_printer.children (self)
@value{GDBN} will call this method on a pretty-printer to compute the
children of the pretty-printer's value.

This method must return an object conforming to the Python iterator
protocol.  Each item returned by the iterator must be a tuple holding
two elements.  The first element is the ``name'' of the child; the
second element is the child's value.  The value can be any Python
object which is convertible to a @value{GDBN} value.

This method is optional.  If it does not exist, @value{GDBN} will act
as though the value has no children.

For efficiency, the @code{children} method should lazily compute its
results.  This will let @value{GDBN} read as few elements as
necessary, for example when various print settings (@pxref{Print
Settings}) or @code{-var-list-children} (@pxref{GDB/MI Variable
Objects}) limit the number of elements to be displayed.

Children may be hidden from display based on the value of @samp{set
print max-depth} (@pxref{Print Settings}).
@end defun

@defun pretty_printer.display_hint (self)
The CLI may call this method and use its result to change the
formatting of a value.  The result will also be supplied to an MI
consumer as a @samp{displayhint} attribute of the variable being
printed.

This method is optional.  If it does exist, this method must return a
string or the special value @code{None}.

Some display hints are predefined by @value{GDBN}:

@table @samp
@item array
Indicate that the object being printed is ``array-like''.  The CLI
uses this to respect parameters such as @code{set print elements} and
@code{set print array}.

@item map
Indicate that the object being printed is ``map-like'', and that the
children of this value can be assumed to alternate between keys and
values.

@item string
Indicate that the object being printed is ``string-like''.  If the
printer's @code{to_string} method returns a Python string of some
kind, then @value{GDBN} will call its internal language-specific
string-printing function to format the string.  For the CLI this means
adding quotation marks, possibly escaping some characters, respecting
@code{set print elements}, and the like.
@end table

The special value @code{None} causes @value{GDBN} to apply the default
display rules.
@end defun

@defun pretty_printer.to_string (self)
@value{GDBN} will call this method to display the string
representation of the value passed to the object's constructor.

When printing from the CLI, if the @code{to_string} method exists,
then @value{GDBN} will prepend its result to the values returned by
@code{children}.  Exactly how this formatting is done is dependent on
the display hint, and may change as more hints are added.  Also,
depending on the print settings (@pxref{Print Settings}), the CLI may
print just the result of @code{to_string} in a stack trace, omitting
the result of @code{children}.

If this method returns a string, it is printed verbatim.

Otherwise, if this method returns an instance of @code{gdb.Value},
then @value{GDBN} prints this value.  This may result in a call to
another pretty-printer.

If instead the method returns a Python value which is convertible to a
@code{gdb.Value}, then @value{GDBN} performs the conversion and prints
the resulting value.  Again, this may result in a call to another
pretty-printer.  Python scalars (integers, floats, and booleans) and
strings are convertible to @code{gdb.Value}; other types are not.

Finally, if this method returns @code{None} then no further operations
are peformed in this method and nothing is printed.

If the result is not one of these types, an exception is raised.
@end defun

@value{GDBN} provides a function which can be used to look up the
default pretty-printer for a @code{gdb.Value}:

@findex gdb.default_visualizer
@defun gdb.default_visualizer (value)
This function takes a @code{gdb.Value} object as an argument.  If a
pretty-printer for this value exists, then it is returned.  If no such
printer exists, then this returns @code{None}.
@end defun

@node Selecting Pretty-Printers
@subsubsection Selecting Pretty-Printers
@cindex selecting python pretty-printers

@value{GDBN} provides several ways to register a pretty-printer:
globally, per program space, and per objfile.  When choosing how to
register your pretty-printer, a good rule is to register it with the
smallest scope possible: that is prefer a specific objfile first, then
a program space, and only register a printer globally as a last
resort.

@findex gdb.pretty_printers
@defvar gdb.pretty_printers
The Python list @code{gdb.pretty_printers} contains an array of
functions or callable objects that have been registered via addition
as a pretty-printer.  Printers in this list are called @code{global}
printers, they're available when debugging all inferiors.
@end defvar

Each @code{gdb.Progspace} contains a @code{pretty_printers} attribute.
Each @code{gdb.Objfile} also contains a @code{pretty_printers}
attribute.

Each function on these lists is passed a single @code{gdb.Value}
argument and should return a pretty-printer object conforming to the
interface definition above (@pxref{Pretty Printing API}).  If a function
cannot create a pretty-printer for the value, it should return
@code{None}.

@value{GDBN} first checks the @code{pretty_printers} attribute of each
@code{gdb.Objfile} in the current program space and iteratively calls
each enabled lookup routine in the list for that @code{gdb.Objfile}
until it receives a pretty-printer object.
If no pretty-printer is found in the objfile lists, @value{GDBN} then
searches the pretty-printer list of the current program space,
calling each enabled function until an object is returned.
After these lists have been exhausted, it tries the global
@code{gdb.pretty_printers} list, again calling each enabled function until an
object is returned.

The order in which the objfiles are searched is not specified.  For a
given list, functions are always invoked from the head of the list,
and iterated over sequentially until the end of the list, or a printer
object is returned.

For various reasons a pretty-printer may not work.
For example, the underlying data structure may have changed and
the pretty-printer is out of date.

The consequences of a broken pretty-printer are severe enough that
@value{GDBN} provides support for enabling and disabling individual
printers.  For example, if @code{print frame-arguments} is on,
a backtrace can become highly illegible if any argument is printed
with a broken printer.

Pretty-printers are enabled and disabled by attaching an @code{enabled}
attribute to the registered function or callable object.  If this attribute
is present and its value is @code{False}, the printer is disabled, otherwise
the printer is enabled.

@node Writing a Pretty-Printer
@subsubsection Writing a Pretty-Printer
@cindex writing a pretty-printer

A pretty-printer consists of two parts: a lookup function to detect
if the type is supported, and the printer itself.

Here is an example showing how a @code{std::string} printer might be
written.  @xref{Pretty Printing API}, for details on the API this class
must provide.

@smallexample
class StdStringPrinter(object):
    "Print a std::string"

    def __init__(self, val):
        self.val = val

    def to_string(self):
        return self.val['_M_dataplus']['_M_p']

    def display_hint(self):
        return 'string'
@end smallexample

And here is an example showing how a lookup function for the printer
example above might be written.

@smallexample
def str_lookup_function(val):
    lookup_tag = val.type.tag
    if lookup_tag is None:
        return None
    regex = re.compile("^std::basic_string<char,.*>$")
    if regex.match(lookup_tag):
        return StdStringPrinter(val)
    return None
@end smallexample

The example lookup function extracts the value's type, and attempts to
match it to a type that it can pretty-print.  If it is a type the
printer can pretty-print, it will return a printer object.  If not, it
returns @code{None}.

We recommend that you put your core pretty-printers into a Python
package.  If your pretty-printers are for use with a library, we
further recommend embedding a version number into the package name.
This practice will enable @value{GDBN} to load multiple versions of
your pretty-printers at the same time, because they will have
different names.

You should write auto-loaded code (@pxref{Python Auto-loading}) such that it
can be evaluated multiple times without changing its meaning.  An
ideal auto-load file will consist solely of @code{import}s of your
printer modules, followed by a call to a register pretty-printers with
the current objfile.

Taken as a whole, this approach will scale nicely to multiple
inferiors, each potentially using a different library version.
Embedding a version number in the Python package name will ensure that
@value{GDBN} is able to load both sets of printers simultaneously.
Then, because the search for pretty-printers is done by objfile, and
because your auto-loaded code took care to register your library's
printers with a specific objfile, @value{GDBN} will find the correct
printers for the specific version of the library used by each
inferior.

To continue the @code{std::string} example (@pxref{Pretty Printing API}),
this code might appear in @code{gdb.libstdcxx.v6}:

@smallexample
def register_printers(objfile):
    objfile.pretty_printers.append(str_lookup_function)
@end smallexample

@noindent
And then the corresponding contents of the auto-load file would be:

@smallexample
import gdb.libstdcxx.v6
gdb.libstdcxx.v6.register_printers(gdb.current_objfile())
@end smallexample

The previous example illustrates a basic pretty-printer.
There are a few things that can be improved on.
The printer doesn't have a name, making it hard to identify in a
list of installed printers.  The lookup function has a name, but
lookup functions can have arbitrary, even identical, names.

Second, the printer only handles one type, whereas a library typically has
several types.  One could install a lookup function for each desired type
in the library, but one could also have a single lookup function recognize
several types.  The latter is the conventional way this is handled.
If a pretty-printer can handle multiple data types, then its
@dfn{subprinters} are the printers for the individual data types.

The @code{gdb.printing} module provides a formal way of solving these
problems (@pxref{gdb.printing}).
Here is another example that handles multiple types.

These are the types we are going to pretty-print:

@smallexample
struct foo @{ int a, b; @};
struct bar @{ struct foo x, y; @};
@end smallexample

Here are the printers:

@smallexample
class fooPrinter:
    """Print a foo object."""

    def __init__(self, val):
        self.val = val

    def to_string(self):
        return ("a=<" + str(self.val["a"]) +
                "> b=<" + str(self.val["b"]) + ">")

class barPrinter:
    """Print a bar object."""

    def __init__(self, val):
        self.val = val

    def to_string(self):
        return ("x=<" + str(self.val["x"]) +
                "> y=<" + str(self.val["y"]) + ">")
@end smallexample

This example doesn't need a lookup function, that is handled by the
@code{gdb.printing} module.  Instead a function is provided to build up
the object that handles the lookup.

@smallexample
import gdb.printing

def build_pretty_printer():
    pp = gdb.printing.RegexpCollectionPrettyPrinter(
        "my_library")
    pp.add_printer('foo', '^foo$', fooPrinter)
    pp.add_printer('bar', '^bar$', barPrinter)
    return pp
@end smallexample

And here is the autoload support:

@smallexample
import gdb.printing
import my_library
gdb.printing.register_pretty_printer(
    gdb.current_objfile(),
    my_library.build_pretty_printer())
@end smallexample

Finally, when this printer is loaded into @value{GDBN}, here is the
corresponding output of @samp{info pretty-printer}:

@smallexample
(gdb) info pretty-printer
my_library.so:
  my_library
    foo
    bar
@end smallexample

@node Type Printing API
@subsubsection Type Printing API
@cindex type printing API for Python

@value{GDBN} provides a way for Python code to customize type display.
This is mainly useful for substituting canonical typedef names for
types.

@cindex type printer
A @dfn{type printer} is just a Python object conforming to a certain
protocol.  A simple base class implementing the protocol is provided;
see @ref{gdb.types}.  A type printer must supply at least:

@defivar type_printer enabled
A boolean which is True if the printer is enabled, and False
otherwise.  This is manipulated by the @code{enable type-printer}
and @code{disable type-printer} commands.
@end defivar

@defivar type_printer name
The name of the type printer.  This must be a string.  This is used by
the @code{enable type-printer} and @code{disable type-printer}
commands.
@end defivar

@defmethod type_printer instantiate (self)
This is called by @value{GDBN} at the start of type-printing.  It is
only called if the type printer is enabled.  This method must return a
new object that supplies a @code{recognize} method, as described below.
@end defmethod


When displaying a type, say via the @code{ptype} command, @value{GDBN}
will compute a list of type recognizers.  This is done by iterating
first over the per-objfile type printers (@pxref{Objfiles In Python}),
followed by the per-progspace type printers (@pxref{Progspaces In
Python}), and finally the global type printers.

@value{GDBN} will call the @code{instantiate} method of each enabled
type printer.  If this method returns @code{None}, then the result is
ignored; otherwise, it is appended to the list of recognizers.

Then, when @value{GDBN} is going to display a type name, it iterates
over the list of recognizers.  For each one, it calls the recognition
function, stopping if the function returns a non-@code{None} value.
The recognition function is defined as:

@defmethod type_recognizer recognize (self, type)
If @var{type} is not recognized, return @code{None}.  Otherwise,
return a string which is to be printed as the name of @var{type}.
The @var{type} argument will be an instance of @code{gdb.Type}
(@pxref{Types In Python}).
@end defmethod

@value{GDBN} uses this two-pass approach so that type printers can
efficiently cache information without holding on to it too long.  For
example, it can be convenient to look up type information in a type
printer and hold it for a recognizer's lifetime; if a single pass were
done then type printers would have to make use of the event system in
order to avoid holding information that could become stale as the
inferior changed.

@node Frame Filter API
@subsubsection Filtering Frames
@cindex frame filters api

Frame filters are Python objects that manipulate the visibility of a
frame or frames when a backtrace (@pxref{Backtrace}) is printed by
@value{GDBN}.

Only commands that print a backtrace, or, in the case of @sc{gdb/mi}
commands (@pxref{GDB/MI}), those that return a collection of frames
are affected.  The commands that work with frame filters are:

@code{backtrace} (@pxref{backtrace-command,, The backtrace command}),
@code{-stack-list-frames}
(@pxref{-stack-list-frames,, The -stack-list-frames command}),
@code{-stack-list-variables} (@pxref{-stack-list-variables,, The
-stack-list-variables command}), @code{-stack-list-arguments}
@pxref{-stack-list-arguments,, The -stack-list-arguments command}) and
@code{-stack-list-locals} (@pxref{-stack-list-locals,, The
-stack-list-locals command}).

A frame filter works by taking an iterator as an argument, applying
actions to the contents of that iterator, and returning another
iterator (or, possibly, the same iterator it was provided in the case
where the filter does not perform any operations).  Typically, frame
filters utilize tools such as the Python's @code{itertools} module to
work with and create new iterators from the source iterator.
Regardless of how a filter chooses to apply actions, it must not alter
the underlying @value{GDBN} frame or frames, or attempt to alter the
call-stack within @value{GDBN}.  This preserves data integrity within
@value{GDBN}.  Frame filters are executed on a priority basis and care
should be taken that some frame filters may have been executed before,
and that some frame filters will be executed after.

An important consideration when designing frame filters, and well
worth reflecting upon, is that frame filters should avoid unwinding
the call stack if possible.  Some stacks can run very deep, into the
tens of thousands in some cases.  To search every frame when a frame
filter executes may be too expensive at that step.  The frame filter
cannot know how many frames it has to iterate over, and it may have to
iterate through them all.  This ends up duplicating effort as
@value{GDBN} performs this iteration when it prints the frames.  If
the filter can defer unwinding frames until frame decorators are
executed, after the last filter has executed, it should.  @xref{Frame
Decorator API}, for more information on decorators.  Also, there are
examples for both frame decorators and filters in later chapters.
@xref{Writing a Frame Filter}, for more information.

The Python dictionary @code{gdb.frame_filters} contains key/object
pairings that comprise a frame filter.  Frame filters in this
dictionary are called @code{global} frame filters, and they are
available when debugging all inferiors.  These frame filters must
register with the dictionary directly.  In addition to the
@code{global} dictionary, there are other dictionaries that are loaded
with different inferiors via auto-loading (@pxref{Python
Auto-loading}).  The two other areas where frame filter dictionaries
can be found are: @code{gdb.Progspace} which contains a
@code{frame_filters} dictionary attribute, and each @code{gdb.Objfile}
object which also contains a @code{frame_filters} dictionary
attribute.

When a command is executed from @value{GDBN} that is compatible with
frame filters, @value{GDBN} combines the @code{global},
@code{gdb.Progspace} and all @code{gdb.Objfile} dictionaries currently
loaded.  All of the @code{gdb.Objfile} dictionaries are combined, as
several frames, and thus several object files, might be in use.
@value{GDBN} then prunes any frame filter whose @code{enabled}
attribute is @code{False}.  This pruned list is then sorted according
to the @code{priority} attribute in each filter.

Once the dictionaries are combined, pruned and sorted, @value{GDBN}
creates an iterator which wraps each frame in the call stack in a
@code{FrameDecorator} object, and calls each filter in order.  The
output from the previous filter will always be the input to the next
filter, and so on.

Frame filters have a mandatory interface which each frame filter must
implement, defined here:

@defun FrameFilter.filter (iterator)
@value{GDBN} will call this method on a frame filter when it has
reached the order in the priority list for that filter.

For example, if there are four frame filters:

@smallexample
Name         Priority

Filter1      5
Filter2      10
Filter3      100
Filter4      1
@end smallexample

The order that the frame filters will be called is:

@smallexample
Filter3 -> Filter2 -> Filter1 -> Filter4
@end smallexample

Note that the output from @code{Filter3} is passed to the input of
@code{Filter2}, and so on.

This @code{filter} method is passed a Python iterator.  This iterator
contains a sequence of frame decorators that wrap each
@code{gdb.Frame}, or a frame decorator that wraps another frame
decorator.  The first filter that is executed in the sequence of frame
filters will receive an iterator entirely comprised of default
@code{FrameDecorator} objects.  However, after each frame filter is
executed, the previous frame filter may have wrapped some or all of
the frame decorators with their own frame decorator.  As frame
decorators must also conform to a mandatory interface, these
decorators can be assumed to act in a uniform manner (@pxref{Frame
Decorator API}).

This method must return an object conforming to the Python iterator
protocol.  Each item in the iterator must be an object conforming to
the frame decorator interface.  If a frame filter does not wish to
perform any operations on this iterator, it should return that
iterator untouched.

This method is not optional.  If it does not exist, @value{GDBN} will
raise and print an error.
@end defun

@defvar FrameFilter.name
The @code{name} attribute must be Python string which contains the
name of the filter displayed by @value{GDBN} (@pxref{Frame Filter
Management}).  This attribute may contain any combination of letters
or numbers.  Care should be taken to ensure that it is unique.  This
attribute is mandatory.
@end defvar

@defvar FrameFilter.enabled
The @code{enabled} attribute must be Python boolean.  This attribute
indicates to @value{GDBN} whether the frame filter is enabled, and
should be considered when frame filters are executed.  If
@code{enabled} is @code{True}, then the frame filter will be executed
when any of the backtrace commands detailed earlier in this chapter
are executed.  If @code{enabled} is @code{False}, then the frame
filter will not be executed.  This attribute is mandatory.
@end defvar

@defvar FrameFilter.priority
The @code{priority} attribute must be Python integer.  This attribute
controls the order of execution in relation to other frame filters.
There are no imposed limits on the range of @code{priority} other than
it must be a valid integer.  The higher the @code{priority} attribute,
the sooner the frame filter will be executed in relation to other
frame filters.  Although @code{priority} can be negative, it is
recommended practice to assume zero is the lowest priority that a
frame filter can be assigned.  Frame filters that have the same
priority are executed in unsorted order in that priority slot.  This
attribute is mandatory.  100 is a good default priority.
@end defvar

@node Frame Decorator API
@subsubsection Decorating Frames
@cindex frame decorator api

Frame decorators are sister objects to frame filters (@pxref{Frame
Filter API}).  Frame decorators are applied by a frame filter and can
only be used in conjunction with frame filters.

The purpose of a frame decorator is to customize the printed content
of each @code{gdb.Frame} in commands where frame filters are executed.
This concept is called decorating a frame.  Frame decorators decorate
a @code{gdb.Frame} with Python code contained within each API call.
This separates the actual data contained in a @code{gdb.Frame} from
the decorated data produced by a frame decorator.  This abstraction is
necessary to maintain integrity of the data contained in each
@code{gdb.Frame}.

Frame decorators have a mandatory interface, defined below.

@value{GDBN} already contains a frame decorator called
@code{FrameDecorator}.  This contains substantial amounts of
boilerplate code to decorate the content of a @code{gdb.Frame}.  It is
recommended that other frame decorators inherit and extend this
object, and only to override the methods needed.

@tindex gdb.FrameDecorator
@code{FrameDecorator} is defined in the Python module
@code{gdb.FrameDecorator}, so your code can import it like:
@smallexample
from gdb.FrameDecorator import FrameDecorator
@end smallexample

@defun FrameDecorator.elided (self)

The @code{elided} method groups frames together in a hierarchical
system.  An example would be an interpreter, where multiple low-level
frames make up a single call in the interpreted language.  In this
example, the frame filter would elide the low-level frames and present
a single high-level frame, representing the call in the interpreted
language, to the user.

The @code{elided} function must return an iterable and this iterable
must contain the frames that are being elided wrapped in a suitable
frame decorator.  If no frames are being elided this function may
return an empty iterable, or @code{None}.  Elided frames are indented
from normal frames in a @code{CLI} backtrace, or in the case of
@code{GDB/MI}, are placed in the @code{children} field of the eliding
frame.

It is the frame filter's task to also filter out the elided frames from
the source iterator.  This will avoid printing the frame twice.
@end defun

@defun FrameDecorator.function (self)

This method returns the name of the function in the frame that is to
be printed.

This method must return a Python string describing the function, or
@code{None}.

If this function returns @code{None}, @value{GDBN} will not print any
data for this field.
@end defun

@defun FrameDecorator.address (self)

This method returns the address of the frame that is to be printed.

This method must return a Python numeric integer type of sufficient
size to describe the address of the frame, or @code{None}.

If this function returns a @code{None}, @value{GDBN} will not print
any data for this field.
@end defun

@defun FrameDecorator.filename (self)

This method returns the filename and path associated with this frame.

This method must return a Python string containing the filename and
the path to the object file backing the frame, or @code{None}.

If this function returns a @code{None}, @value{GDBN} will not print
any data for this field.
@end defun

@defun FrameDecorator.line (self):

This method returns the line number associated with the current
position within the function addressed by this frame.

This method must return a Python integer type, or @code{None}.

If this function returns a @code{None}, @value{GDBN} will not print
any data for this field.
@end defun

@defun FrameDecorator.frame_args (self)
@anchor{frame_args}

This method must return an iterable, or @code{None}.  Returning an
empty iterable, or @code{None} means frame arguments will not be
printed for this frame.  This iterable must contain objects that
implement two methods, described here.

This object must implement a @code{symbol} method which takes a
single @code{self} parameter and must return a @code{gdb.Symbol}
(@pxref{Symbols In Python}), or a Python string.  The object must also
implement a @code{value} method which takes a single @code{self}
parameter and must return a @code{gdb.Value} (@pxref{Values From
Inferior}), a Python value, or @code{None}.  If the @code{value}
method returns @code{None}, and the @code{argument} method returns a
@code{gdb.Symbol}, @value{GDBN} will look-up and print the value of
the @code{gdb.Symbol} automatically.

A brief example:

@smallexample
class SymValueWrapper():

    def __init__(self, symbol, value):
        self.sym = symbol
        self.val = value

    def value(self):
        return self.val

    def symbol(self):
        return self.sym

class SomeFrameDecorator()
...
...
    def frame_args(self):
        args = []
        try:
            block = self.inferior_frame.block()
        except:
            return None

        # Iterate over all symbols in a block.  Only add
        # symbols that are arguments.
        for sym in block:
            if not sym.is_argument:
                continue
            args.append(SymValueWrapper(sym,None))

        # Add example synthetic argument.
        args.append(SymValueWrapper(``foo'', 42))

        return args
@end smallexample
@end defun

@defun FrameDecorator.frame_locals (self)

This method must return an iterable or @code{None}.  Returning an
empty iterable, or @code{None} means frame local arguments will not be
printed for this frame.

The object interface, the description of the various strategies for
reading frame locals, and the example are largely similar to those
described in the @code{frame_args} function, (@pxref{frame_args,,The
frame filter frame_args function}).  Below is a modified example:

@smallexample
class SomeFrameDecorator()
...
...
    def frame_locals(self):
        vars = []
        try:
            block = self.inferior_frame.block()
        except:
            return None

        # Iterate over all symbols in a block.  Add all
        # symbols, except arguments.
        for sym in block:
            if sym.is_argument:
                continue
            vars.append(SymValueWrapper(sym,None))

        # Add an example of a synthetic local variable.
        vars.append(SymValueWrapper(``bar'', 99))

        return vars
@end smallexample
@end defun

@defun FrameDecorator.inferior_frame (self):

This method must return the underlying @code{gdb.Frame} that this
frame decorator is decorating.  @value{GDBN} requires the underlying
frame for internal frame information to determine how to print certain
values when printing a frame.
@end defun

@node Writing a Frame Filter
@subsubsection Writing a Frame Filter
@cindex writing a frame filter

There are three basic elements that a frame filter must implement: it
must correctly implement the documented interface (@pxref{Frame Filter
API}), it must register itself with @value{GDBN}, and finally, it must
decide if it is to work on the data provided by @value{GDBN}.  In all
cases, whether it works on the iterator or not, each frame filter must
return an iterator.  A bare-bones frame filter follows the pattern in
the following example.

@smallexample
import gdb

class FrameFilter():

    def __init__(self):
        # Frame filter attribute creation.
        #
        # 'name' is the name of the filter that GDB will display.
        #
        # 'priority' is the priority of the filter relative to other
        # filters.
        #
        # 'enabled' is a boolean that indicates whether this filter is
        # enabled and should be executed.

        self.name = "Foo"
        self.priority = 100
        self.enabled = True

        # Register this frame filter with the global frame_filters
        # dictionary.
        gdb.frame_filters[self.name] = self

    def filter(self, frame_iter):
        # Just return the iterator.
        return frame_iter
@end smallexample

The frame filter in the example above implements the three
requirements for all frame filters.  It implements the API, self
registers, and makes a decision on the iterator (in this case, it just
returns the iterator untouched).

The first step is attribute creation and assignment, and as shown in
the comments the filter assigns the following attributes:  @code{name},
@code{priority} and whether the filter should be enabled with the
@code{enabled} attribute.

The second step is registering the frame filter with the dictionary or
dictionaries that the frame filter has interest in.  As shown in the
comments, this filter just registers itself with the global dictionary
@code{gdb.frame_filters}.  As noted earlier, @code{gdb.frame_filters}
is a dictionary that is initialized in the @code{gdb} module when
@value{GDBN} starts.  What dictionary a filter registers with is an
important consideration.  Generally, if a filter is specific to a set
of code, it should be registered either in the @code{objfile} or
@code{progspace} dictionaries as they are specific to the program
currently loaded in @value{GDBN}.  The global dictionary is always
present in @value{GDBN} and is never unloaded.  Any filters registered
with the global dictionary will exist until @value{GDBN} exits.  To
avoid filters that may conflict, it is generally better to register
frame filters against the dictionaries that more closely align with
the usage of the filter currently in question.  @xref{Python
Auto-loading}, for further information on auto-loading Python scripts.

@value{GDBN} takes a hands-off approach to frame filter registration,
therefore it is the frame filter's responsibility to ensure
registration has occurred, and that any exceptions are handled
appropriately.  In particular, you may wish to handle exceptions
relating to Python dictionary key uniqueness.  It is mandatory that
the dictionary key is the same as frame filter's @code{name}
attribute.  When a user manages frame filters (@pxref{Frame Filter
Management}), the names @value{GDBN} will display are those contained
in the @code{name} attribute.

The final step of this example is the implementation of the
@code{filter} method.  As shown in the example comments, we define the
@code{filter} method and note that the method must take an iterator,
and also must return an iterator.  In this bare-bones example, the
frame filter is not very useful as it just returns the iterator
untouched.  However this is a valid operation for frame filters that
have the @code{enabled} attribute set, but decide not to operate on
any frames.

In the next example, the frame filter operates on all frames and
utilizes a frame decorator to perform some work on the frames.
@xref{Frame Decorator API}, for further information on the frame
decorator interface.

This example works on inlined frames.  It highlights frames which are
inlined by tagging them with an ``[inlined]'' tag.  By applying a
frame decorator to all frames with the Python @code{itertools imap}
method, the example defers actions to the frame decorator.  Frame
decorators are only processed when @value{GDBN} prints the backtrace.

This introduces a new decision making topic: whether to perform
decision making operations at the filtering step, or at the printing
step.  In this example's approach, it does not perform any filtering
decisions at the filtering step beyond mapping a frame decorator to
each frame.  This allows the actual decision making to be performed
when each frame is printed.  This is an important consideration, and
well worth reflecting upon when designing a frame filter.  An issue
that frame filters should avoid is unwinding the stack if possible.
Some stacks can run very deep, into the tens of thousands in some
cases.  To search every frame to determine if it is inlined ahead of
time may be too expensive at the filtering step.  The frame filter
cannot know how many frames it has to iterate over, and it would have
to iterate through them all.  This ends up duplicating effort as
@value{GDBN} performs this iteration when it prints the frames.

In this example decision making can be deferred to the printing step.
As each frame is printed, the frame decorator can examine each frame
in turn when @value{GDBN} iterates.  From a performance viewpoint,
this is the most appropriate decision to make as it avoids duplicating
the effort that the printing step would undertake anyway.  Also, if
there are many frame filters unwinding the stack during filtering, it
can substantially delay the printing of the backtrace which will
result in large memory usage, and a poor user experience.

@smallexample
class InlineFilter():

    def __init__(self):
        self.name = "InlinedFrameFilter"
        self.priority = 100
        self.enabled = True
        gdb.frame_filters[self.name] = self

    def filter(self, frame_iter):
        frame_iter = itertools.imap(InlinedFrameDecorator,
                                    frame_iter)
        return frame_iter
@end smallexample

This frame filter is somewhat similar to the earlier example, except
that the @code{filter} method applies a frame decorator object called
@code{InlinedFrameDecorator} to each element in the iterator.  The
@code{imap} Python method is light-weight.  It does not proactively
iterate over the iterator, but rather creates a new iterator which
wraps the existing one.

Below is the frame decorator for this example.

@smallexample
class InlinedFrameDecorator(FrameDecorator):

    def __init__(self, fobj):
        super(InlinedFrameDecorator, self).__init__(fobj)

    def function(self):
        frame = self.inferior_frame()
        name = str(frame.name())

        if frame.type() == gdb.INLINE_FRAME:
            name = name + " [inlined]"

        return name
@end smallexample

This frame decorator only defines and overrides the @code{function}
method.  It lets the supplied @code{FrameDecorator}, which is shipped
with @value{GDBN}, perform the other work associated with printing
this frame.

The combination of these two objects create this output from a
backtrace:

@smallexample
#0  0x004004e0 in bar () at inline.c:11
#1  0x00400566 in max [inlined] (b=6, a=12) at inline.c:21
#2  0x00400566 in main () at inline.c:31
@end smallexample

So in the case of this example, a frame decorator is applied to all
frames, regardless of whether they may be inlined or not.  As
@value{GDBN} iterates over the iterator produced by the frame filters,
@value{GDBN} executes each frame decorator which then makes a decision
on what to print in the @code{function} callback.  Using a strategy
like this is a way to defer decisions on the frame content to printing
time.

@subheading Eliding Frames

It might be that the above example is not desirable for representing
inlined frames, and a hierarchical approach may be preferred.  If we
want to hierarchically represent frames, the @code{elided} frame
decorator interface might be preferable.

This example approaches the issue with the @code{elided} method.  This
example is quite long, but very simplistic.  It is out-of-scope for
this section to write a complete example that comprehensively covers
all approaches of finding and printing inlined frames.  However, this
example illustrates the approach an author might use.

This example comprises of three sections.

@smallexample
class InlineFrameFilter():

    def __init__(self):
        self.name = "InlinedFrameFilter"
        self.priority = 100
        self.enabled = True
        gdb.frame_filters[self.name] = self

    def filter(self, frame_iter):
        return ElidingInlineIterator(frame_iter)
@end smallexample

This frame filter is very similar to the other examples.  The only
difference is this frame filter is wrapping the iterator provided to
it (@code{frame_iter}) with a custom iterator called
@code{ElidingInlineIterator}.  This again defers actions to when
@value{GDBN} prints the backtrace, as the iterator is not traversed
until printing.

The iterator for this example is as follows.  It is in this section of
the example where decisions are made on the content of the backtrace.

@smallexample
class ElidingInlineIterator:
    def __init__(self, ii):
        self.input_iterator = ii

    def __iter__(self):
        return self

    def next(self):
        frame = next(self.input_iterator)

        if frame.inferior_frame().type() != gdb.INLINE_FRAME:
            return frame

        try:
            eliding_frame = next(self.input_iterator)
        except StopIteration:
            return frame
        return ElidingFrameDecorator(eliding_frame, [frame])
@end smallexample

This iterator implements the Python iterator protocol.  When the
@code{next} function is called (when @value{GDBN} prints each frame),
the iterator checks if this frame decorator, @code{frame}, is wrapping
an inlined frame.  If it is not, it returns the existing frame decorator
untouched.  If it is wrapping an inlined frame, it assumes that the
inlined frame was contained within the next oldest frame,
@code{eliding_frame}, which it fetches.  It then creates and returns a
frame decorator, @code{ElidingFrameDecorator}, which contains both the
elided frame, and the eliding frame.

@smallexample
class ElidingInlineDecorator(FrameDecorator):

    def __init__(self, frame, elided_frames):
        super(ElidingInlineDecorator, self).__init__(frame)
        self.frame = frame
        self.elided_frames = elided_frames

    def elided(self):
        return iter(self.elided_frames)
@end smallexample

This frame decorator overrides one function and returns the inlined
frame in the @code{elided} method.  As before it lets
@code{FrameDecorator} do the rest of the work involved in printing
this frame.  This produces the following output.

@smallexample
#0  0x004004e0 in bar () at inline.c:11
#2  0x00400529 in main () at inline.c:25
    #1  0x00400529 in max (b=6, a=12) at inline.c:15
@end smallexample

In that output, @code{max} which has been inlined into @code{main} is
printed hierarchically.  Another approach would be to combine the
@code{function} method, and the @code{elided} method to both print a
marker in the inlined frame, and also show the hierarchical
relationship.

@node Unwinding Frames in Python
@subsubsection Unwinding Frames in Python
@cindex unwinding frames in Python

In @value{GDBN} terminology ``unwinding'' is the process of finding
the previous frame (that is, caller's) from the current one.  An
unwinder has three methods.  The first one checks if it can handle
given frame (``sniff'' it).  For the frames it can sniff an unwinder
provides two additional methods: it can return frame's ID, and it can
fetch registers from the previous frame.  A running @value{GDBN}
mantains a list of the unwinders and calls each unwinder's sniffer in
turn until it finds the one that recognizes the current frame.  There
is an API to register an unwinder.

The unwinders that come with @value{GDBN} handle standard frames.
However, mixed language applications (for example, an application
running Java Virtual Machine) sometimes use frame layouts that cannot
be handled by the @value{GDBN} unwinders.  You can write Python code
that can handle such custom frames.

You implement a frame unwinder in Python as a class with which has two
attributes, @code{name} and @code{enabled}, with obvious meanings, and
a single method @code{__call__}, which examines a given frame and
returns an object (an instance of @code{gdb.UnwindInfo class)}
describing it.  If an unwinder does not recognize a frame, it should
return @code{None}.  The code in @value{GDBN} that enables writing
unwinders in Python uses this object to return frame's ID and previous
frame registers when @value{GDBN} core asks for them.

An unwinder should do as little work as possible.  Some otherwise
innocuous operations can cause problems (even crashes, as this code is
not not well-hardened yet).  For example, making an inferior call from
an unwinder is unadvisable, as an inferior call will reset
@value{GDBN}'s stack unwinding process, potentially causing re-entrant
unwinding.

@subheading Unwinder Input

An object passed to an unwinder (a @code{gdb.PendingFrame} instance)
provides a method to read frame's registers:

@defun PendingFrame.read_register (reg)
This method returns the contents of the register @var{reg} in the
frame as a @code{gdb.Value} object.  For a description of the
acceptable values of @var{reg} see
@ref{gdbpy_frame_read_register,,Frame.read_register}.  If @var{reg}
does not name a register for the current architecture, this method
will throw an exception.

Note that this method will always return a @code{gdb.Value} for a
valid register name.  This does not mean that the value will be valid.
For example, you may request a register that an earlier unwinder could
not unwind---the value will be unavailable.  Instead, the
@code{gdb.Value} returned from this method will be lazy; that is, its
underlying bits will not be fetched until it is first used.  So,
attempting to use such a value will cause an exception at the point of
use.

The type of the returned @code{gdb.Value} depends on the register and
the architecture.  It is common for registers to have a scalar type,
like @code{long long}; but many other types are possible, such as
pointer, pointer-to-function, floating point or vector types.
@end defun

It also provides a factory method to create a @code{gdb.UnwindInfo}
instance to be returned to @value{GDBN}:

@defun PendingFrame.create_unwind_info (frame_id)
Returns a new @code{gdb.UnwindInfo} instance identified by given
@var{frame_id}.  The argument is used to build @value{GDBN}'s frame ID
using one of functions provided by @value{GDBN}.  @var{frame_id}'s attributes
determine which function will be used, as follows:

@table @code
@item sp, pc
The frame is identified by the given stack address and PC.  The stack
address must be chosen so that it is constant throughout the lifetime
of the frame, so a typical choice is the value of the stack pointer at
the start of the function---in the DWARF standard, this would be the
``Call Frame Address''.

This is the most common case by far.  The other cases are documented
for completeness but are only useful in specialized situations.

@item sp, pc, special
The frame is identified by the stack address, the PC, and a
``special'' address.  The special address is used on architectures
that can have frames that do not change the stack, but which are still
distinct, for example the IA-64, which has a second stack for
registers.  Both @var{sp} and @var{special} must be constant
throughout the lifetime of the frame.

@item sp
The frame is identified by the stack address only.  Any other stack
frame with a matching @var{sp} will be considered to match this frame.
Inside gdb, this is called a ``wild frame''.  You will never need
this.
@end table

Each attribute value should be an instance of @code{gdb.Value}.

@end defun

@defun PendingFrame.architecture ()
Return the @code{gdb.Architecture} (@pxref{Architectures In Python})
for this @code{gdb.PendingFrame}.  This represents the architecture of
the particular frame being unwound.
@end defun

@defun PendingFrame.level ()
Return an integer, the stack frame level for this frame.
@xref{Frames, ,Stack Frames}.
@end defun

@subheading Unwinder Output: UnwindInfo

Use @code{PendingFrame.create_unwind_info} method described above to
create a @code{gdb.UnwindInfo} instance.  Use the following method to
specify caller registers that have been saved in this frame:

@defun gdb.UnwindInfo.add_saved_register (reg, value)
@var{reg} identifies the register, for a description of the acceptable
values see @ref{gdbpy_frame_read_register,,Frame.read_register}.
@var{value} is a register value (a @code{gdb.Value} object).
@end defun

@subheading Unwinder Skeleton Code

@value{GDBN} comes with the module containing the base @code{Unwinder}
class.  Derive your unwinder class from it and structure the code as
follows:

@smallexample
from gdb.unwinders import Unwinder

class FrameId(object):
    def __init__(self, sp, pc):
        self.sp = sp
        self.pc = pc


class MyUnwinder(Unwinder):
    def __init__(....):
        super(MyUnwinder, self).__init___(<expects unwinder name argument>)

    def __call__(pending_frame):
        if not <we recognize frame>:
            return None
        # Create UnwindInfo.  Usually the frame is identified by the stack 
        # pointer and the program counter.
        sp = pending_frame.read_register(<SP number>)
        pc = pending_frame.read_register(<PC number>)
        unwind_info = pending_frame.create_unwind_info(FrameId(sp, pc))

        # Find the values of the registers in the caller's frame and 
        # save them in the result:
        unwind_info.add_saved_register(<register>, <value>)
        ....

        # Return the result:
        return unwind_info

@end smallexample

@subheading Registering a Unwinder

An object file, a program space, and the @value{GDBN} proper can have
unwinders registered with it.

The @code{gdb.unwinders} module provides the function to register a
unwinder:

@defun gdb.unwinder.register_unwinder (locus, unwinder, replace=False)
@var{locus} is specifies an object file or a program space to which
@var{unwinder} is added.  Passing @code{None} or @code{gdb} adds
@var{unwinder} to the @value{GDBN}'s global unwinder list.  The newly
added @var{unwinder} will be called before any other unwinder from the
same locus.  Two unwinders in the same locus cannot have the same
name.  An attempt to add a unwinder with already existing name raises
an exception unless @var{replace} is @code{True}, in which case the
old unwinder is deleted.
@end defun

@subheading Unwinder Precedence

@value{GDBN} first calls the unwinders from all the object files in no
particular order, then the unwinders from the current program space,
and finally the unwinders from @value{GDBN}.

@node Xmethods In Python
@subsubsection Xmethods In Python
@cindex xmethods in Python

@dfn{Xmethods} are additional methods or replacements for existing
methods of a C@t{++} class.  This feature is useful for those cases
where a method defined in C@t{++} source code could be inlined or
optimized out by the compiler, making it unavailable to @value{GDBN}.
For such cases, one can define an xmethod to serve as a replacement
for the method defined in the C@t{++} source code.  @value{GDBN} will
then invoke the xmethod, instead of the C@t{++} method, to
evaluate expressions.  One can also use xmethods when debugging
with core files.  Moreover, when debugging live programs, invoking an
xmethod need not involve running the inferior (which can potentially
perturb its state).  Hence, even if the C@t{++} method is available, it
is better to use its replacement xmethod if one is defined.

The xmethods feature in Python is available via the concepts of an
@dfn{xmethod matcher} and an @dfn{xmethod worker}.  To
implement an xmethod, one has to implement a matcher and a
corresponding worker for it (more than one worker can be
implemented, each catering to a different overloaded instance of the
method).  Internally, @value{GDBN} invokes the @code{match} method of a
matcher to match the class type and method name.  On a match, the
@code{match} method returns a list of matching @emph{worker} objects.
Each worker object typically corresponds to an overloaded instance of
the xmethod.  They implement a @code{get_arg_types} method which
returns a sequence of types corresponding to the arguments the xmethod
requires.  @value{GDBN} uses this sequence of types to perform
overload resolution and picks a winning xmethod worker.  A winner
is also selected from among the methods @value{GDBN} finds in the
C@t{++} source code.  Next, the winning xmethod worker and the
winning C@t{++} method are compared to select an overall winner.  In
case of a tie between a xmethod worker and a C@t{++} method, the
xmethod worker is selected as the winner.  That is, if a winning
xmethod worker is found to be equivalent to the winning C@t{++}
method, then the xmethod worker is treated as a replacement for
the C@t{++} method.  @value{GDBN} uses the overall winner to invoke the
method.  If the winning xmethod worker is the overall winner, then
the corresponding xmethod is invoked via the @code{__call__} method
of the worker object.

If one wants to implement an xmethod as a replacement for an
existing C@t{++} method, then they have to implement an equivalent
xmethod which has exactly the same name and takes arguments of
exactly the same type as the C@t{++} method.  If the user wants to
invoke the C@t{++} method even though a replacement xmethod is
available for that method, then they can disable the xmethod.

@xref{Xmethod API}, for API to implement xmethods in Python.
@xref{Writing an Xmethod}, for implementing xmethods in Python.

@node Xmethod API
@subsubsection Xmethod API
@cindex xmethod API

The @value{GDBN} Python API provides classes, interfaces and functions
to implement, register and manipulate xmethods.
@xref{Xmethods In Python}.

An xmethod matcher should be an instance of a class derived from
@code{XMethodMatcher} defined in the module @code{gdb.xmethod}, or an
object with similar interface and attributes.  An instance of
@code{XMethodMatcher} has the following attributes:

@defvar name
The name of the matcher.
@end defvar

@defvar enabled
A boolean value indicating whether the matcher is enabled or disabled.
@end defvar

@defvar methods
A list of named methods managed by the matcher.  Each object in the list
is an instance of the class @code{XMethod} defined in the module
@code{gdb.xmethod}, or any object with the following attributes:

@table @code

@item name
Name of the xmethod which should be unique for each xmethod
managed by the matcher.

@item enabled
A boolean value indicating whether the xmethod is enabled or
disabled.

@end table

The class @code{XMethod} is a convenience class with same
attributes as above along with the following constructor:

@defun XMethod.__init__ (self, name)
Constructs an enabled xmethod with name @var{name}.
@end defun
@end defvar

@noindent
The @code{XMethodMatcher} class has the following methods:

@defun XMethodMatcher.__init__ (self, name)
Constructs an enabled xmethod matcher with name @var{name}.  The
@code{methods} attribute is initialized to @code{None}.
@end defun

@defun XMethodMatcher.match (self, class_type, method_name)
Derived classes should override this method.  It should return a
xmethod worker object (or a sequence of xmethod worker
objects) matching the @var{class_type} and @var{method_name}.
@var{class_type} is a @code{gdb.Type} object, and @var{method_name}
is a string value.  If the matcher manages named methods as listed in
its @code{methods} attribute, then only those worker objects whose
corresponding entries in the @code{methods} list are enabled should be
returned.
@end defun

An xmethod worker should be an instance of a class derived from
@code{XMethodWorker} defined in the module @code{gdb.xmethod},
or support the following interface:

@defun XMethodWorker.get_arg_types (self)
This method returns a sequence of @code{gdb.Type} objects corresponding
to the arguments that the xmethod takes.  It can return an empty
sequence or @code{None} if the xmethod does not take any arguments.
If the xmethod takes a single argument, then a single
@code{gdb.Type} object corresponding to it can be returned.
@end defun

@defun XMethodWorker.get_result_type (self, *args)
This method returns a @code{gdb.Type} object representing the type
of the result of invoking this xmethod.
The @var{args} argument is the same tuple of arguments that would be
passed to the @code{__call__} method of this worker.
@end defun

@defun XMethodWorker.__call__ (self, *args)
This is the method which does the @emph{work} of the xmethod.  The
@var{args} arguments is the tuple of arguments to the xmethod.  Each
element in this tuple is a gdb.Value object.  The first element is
always the @code{this} pointer value.
@end defun

For @value{GDBN} to lookup xmethods, the xmethod matchers
should be registered using the following function defined in the module
@code{gdb.xmethod}:

@defun register_xmethod_matcher (locus, matcher, replace=False)
The @code{matcher} is registered with @code{locus}, replacing an
existing matcher with the same name as @code{matcher} if
@code{replace} is @code{True}.  @code{locus} can be a
@code{gdb.Objfile} object (@pxref{Objfiles In Python}), or a
@code{gdb.Progspace} object (@pxref{Progspaces In Python}), or
@code{None}.  If it is @code{None}, then @code{matcher} is registered
globally.
@end defun

@node Writing an Xmethod
@subsubsection Writing an Xmethod
@cindex writing xmethods in Python

Implementing xmethods in Python will require implementing xmethod
matchers and xmethod workers (@pxref{Xmethods In Python}).  Consider
the following C@t{++} class:

@smallexample
class MyClass
@{
public:
  MyClass (int a) : a_(a) @{ @}

  int geta (void) @{ return a_; @}
  int operator+ (int b);

private:
  int a_;
@};

int
MyClass::operator+ (int b)
@{
  return a_ + b;
@}
@end smallexample

@noindent
Let us define two xmethods for the class @code{MyClass}, one
replacing the method @code{geta}, and another adding an overloaded
flavor of @code{operator+} which takes a @code{MyClass} argument (the
C@t{++} code above already has an overloaded @code{operator+}
which takes an @code{int} argument).  The xmethod matcher can be
defined as follows:

@smallexample
class MyClass_geta(gdb.xmethod.XMethod):
    def __init__(self):
        gdb.xmethod.XMethod.__init__(self, 'geta')
 
    def get_worker(self, method_name):
        if method_name == 'geta':
            return MyClassWorker_geta()
 
 
class MyClass_sum(gdb.xmethod.XMethod):
    def __init__(self):
        gdb.xmethod.XMethod.__init__(self, 'sum')
 
    def get_worker(self, method_name):
        if method_name == 'operator+':
            return MyClassWorker_plus()
 
 
class MyClassMatcher(gdb.xmethod.XMethodMatcher):
    def __init__(self):
        gdb.xmethod.XMethodMatcher.__init__(self, 'MyClassMatcher')
        # List of methods 'managed' by this matcher
        self.methods = [MyClass_geta(), MyClass_sum()]
 
    def match(self, class_type, method_name):
        if class_type.tag != 'MyClass':
            return None
        workers = []
        for method in self.methods:
            if method.enabled:
                worker = method.get_worker(method_name)
                if worker:
                    workers.append(worker)
 
        return workers
@end smallexample

@noindent
Notice that the @code{match} method of @code{MyClassMatcher} returns
a worker object of type @code{MyClassWorker_geta} for the @code{geta}
method, and a worker object of type @code{MyClassWorker_plus} for the
@code{operator+} method.  This is done indirectly via helper classes
derived from @code{gdb.xmethod.XMethod}.  One does not need to use the
@code{methods} attribute in a matcher as it is optional.  However, if a
matcher manages more than one xmethod, it is a good practice to list the
xmethods in the @code{methods} attribute of the matcher.  This will then
facilitate enabling and disabling individual xmethods via the
@code{enable/disable} commands.  Notice also that a worker object is
returned only if the corresponding entry in the @code{methods} attribute
of the matcher is enabled.

The implementation of the worker classes returned by the matcher setup
above is as follows:

@smallexample
class MyClassWorker_geta(gdb.xmethod.XMethodWorker):
    def get_arg_types(self):
        return None

    def get_result_type(self, obj):
        return gdb.lookup_type('int')
 
    def __call__(self, obj):
        return obj['a_']
 
 
class MyClassWorker_plus(gdb.xmethod.XMethodWorker):
    def get_arg_types(self):
        return gdb.lookup_type('MyClass')

    def get_result_type(self, obj):
        return gdb.lookup_type('int')
 
    def __call__(self, obj, other):
        return obj['a_'] + other['a_']
@end smallexample

For @value{GDBN} to actually lookup a xmethod, it has to be
registered with it.  The matcher defined above is registered with
@value{GDBN} globally as follows:

@smallexample
gdb.xmethod.register_xmethod_matcher(None, MyClassMatcher())
@end smallexample

If an object @code{obj} of type @code{MyClass} is initialized in C@t{++}
code as follows:

@smallexample
MyClass obj(5);
@end smallexample

@noindent
then, after loading the Python script defining the xmethod matchers
and workers into @code{GDBN}, invoking the method @code{geta} or using
the operator @code{+} on @code{obj} will invoke the xmethods
defined above:

@smallexample
(gdb) p obj.geta()
$1 = 5

(gdb) p obj + obj
$2 = 10
@end smallexample

Consider another example with a C++ template class:

@smallexample
template <class T>
class MyTemplate
@{
public:
  MyTemplate () : dsize_(10), data_ (new T [10]) @{ @}
  ~MyTemplate () @{ delete [] data_; @}
 
  int footprint (void)
  @{
    return sizeof (T) * dsize_ + sizeof (MyTemplate<T>);
  @}
 
private:
  int dsize_;
  T *data_;
@};
@end smallexample

Let us implement an xmethod for the above class which serves as a
replacement for the @code{footprint} method.  The full code listing
of the xmethod workers and xmethod matchers is as follows:

@smallexample
class MyTemplateWorker_footprint(gdb.xmethod.XMethodWorker):
    def __init__(self, class_type):
        self.class_type = class_type

    def get_arg_types(self):
        return None

    def get_result_type(self):
        return gdb.lookup_type('int')

    def __call__(self, obj):
        return (self.class_type.sizeof +
                obj['dsize_'] *
                self.class_type.template_argument(0).sizeof)
 
 
class MyTemplateMatcher_footprint(gdb.xmethod.XMethodMatcher):
    def __init__(self):
        gdb.xmethod.XMethodMatcher.__init__(self, 'MyTemplateMatcher')
 
    def match(self, class_type, method_name):
        if (re.match('MyTemplate<[ \t\n]*[_a-zA-Z][ _a-zA-Z0-9]*>',
                     class_type.tag) and
            method_name == 'footprint'):
            return MyTemplateWorker_footprint(class_type)
@end smallexample

Notice that, in this example, we have not used the @code{methods}
attribute of the matcher as the matcher manages only one xmethod.  The
user can enable/disable this xmethod by enabling/disabling the matcher
itself.

@node Inferiors In Python
@subsubsection Inferiors In Python
@cindex inferiors in Python

@findex gdb.Inferior
Programs which are being run under @value{GDBN} are called inferiors
(@pxref{Inferiors Connections and Programs}).  Python scripts can access
information about and manipulate inferiors controlled by @value{GDBN}
via objects of the @code{gdb.Inferior} class.

The following inferior-related functions are available in the @code{gdb}
module:

@defun gdb.inferiors ()
Return a tuple containing all inferior objects.
@end defun

@defun gdb.selected_inferior ()
Return an object representing the current inferior.
@end defun

A @code{gdb.Inferior} object has the following attributes:

@defvar Inferior.num
ID of inferior, as assigned by GDB.
@end defvar

@defvar Inferior.connection_num
ID of inferior's connection as assigned by @value{GDBN}, or None if
the inferior is not connected to a target.
@xref{Inferiors Connections and Programs}.
@end defvar

@defvar Inferior.pid
Process ID of the inferior, as assigned by the underlying operating
system.
@end defvar

@defvar Inferior.was_attached
Boolean signaling whether the inferior was created using `attach', or
started by @value{GDBN} itself.
@end defvar

@defvar Inferior.progspace
The inferior's program space.  @xref{Progspaces In Python}.
@end defvar

A @code{gdb.Inferior} object has the following methods:

@defun Inferior.is_valid ()
Returns @code{True} if the @code{gdb.Inferior} object is valid,
@code{False} if not.  A @code{gdb.Inferior} object will become invalid
if the inferior no longer exists within @value{GDBN}.  All other
@code{gdb.Inferior} methods will throw an exception if it is invalid
at the time the method is called.
@end defun

@defun Inferior.threads ()
This method returns a tuple holding all the threads which are valid
when it is called.  If there are no valid threads, the method will
return an empty tuple.
@end defun

@defun Inferior.architecture ()
Return the @code{gdb.Architecture} (@pxref{Architectures In Python})
for this inferior.  This represents the architecture of the inferior
as a whole.  Some platforms can have multiple architectures in a
single address space, so this may not match the architecture of a
particular frame (@pxref{Frames In Python}).
@end defun

@findex Inferior.read_memory
@defun Inferior.read_memory (address, length)
Read @var{length} addressable memory units from the inferior, starting at
@var{address}.  Returns a buffer object, which behaves much like an array
or a string.  It can be modified and given to the
@code{Inferior.write_memory} function.  In Python 3, the return
value is a @code{memoryview} object.
@end defun

@findex Inferior.write_memory
@defun Inferior.write_memory (address, buffer @r{[}, length@r{]})
Write the contents of @var{buffer} to the inferior, starting at
@var{address}.  The @var{buffer} parameter must be a Python object
which supports the buffer protocol, i.e., a string, an array or the
object returned from @code{Inferior.read_memory}.  If given, @var{length}
determines the number of addressable memory units from @var{buffer} to be
written.
@end defun

@findex gdb.search_memory
@defun Inferior.search_memory (address, length, pattern)
Search a region of the inferior memory starting at @var{address} with
the given @var{length} using the search pattern supplied in
@var{pattern}.  The @var{pattern} parameter must be a Python object
which supports the buffer protocol, i.e., a string, an array or the
object returned from @code{gdb.read_memory}.  Returns a Python @code{Long}
containing the address where the pattern was found, or @code{None} if
the pattern could not be found.
@end defun

@findex Inferior.thread_from_handle
@findex Inferior.thread_from_thread_handle
@defun Inferior.thread_from_handle (handle)
Return the thread object corresponding to @var{handle}, a thread
library specific data structure such as @code{pthread_t} for pthreads
library implementations.

The function @code{Inferior.thread_from_thread_handle} provides
the same functionality, but use of @code{Inferior.thread_from_thread_handle}
is deprecated.
@end defun

@node Events In Python
@subsubsection Events In Python
@cindex inferior events in Python

@value{GDBN} provides a general event facility so that Python code can be
notified of various state changes, particularly changes that occur in
the inferior.

An @dfn{event} is just an object that describes some state change.  The
type of the object and its attributes will vary depending on the details
of the change.  All the existing events are described below.

In order to be notified of an event, you must register an event handler
with an @dfn{event registry}.  An event registry is an object in the
@code{gdb.events} module which dispatches particular events.  A registry
provides methods to register and unregister event handlers:

@defun EventRegistry.connect (object)
Add the given callable @var{object} to the registry.  This object will be
called when an event corresponding to this registry occurs.
@end defun

@defun EventRegistry.disconnect (object)
Remove the given @var{object} from the registry.  Once removed, the object
will no longer receive notifications of events.
@end defun

Here is an example:

@smallexample
def exit_handler (event):
    print ("event type: exit")
    print ("exit code: %d" % (event.exit_code))

gdb.events.exited.connect (exit_handler)
@end smallexample

In the above example we connect our handler @code{exit_handler} to the
registry @code{events.exited}.  Once connected, @code{exit_handler} gets
called when the inferior exits.  The argument @dfn{event} in this example is
of type @code{gdb.ExitedEvent}.  As you can see in the example the
@code{ExitedEvent} object has an attribute which indicates the exit code of
the inferior.

The following is a listing of the event registries that are available and
details of the events they emit:

@table @code

@item events.cont
Emits @code{gdb.ThreadEvent}.

Some events can be thread specific when @value{GDBN} is running in non-stop
mode.  When represented in Python, these events all extend
@code{gdb.ThreadEvent}.  Note, this event is not emitted directly; instead,
events which are emitted by this or other modules might extend this event.
Examples of these events are @code{gdb.BreakpointEvent} and
@code{gdb.ContinueEvent}.

@defvar ThreadEvent.inferior_thread
In non-stop mode this attribute will be set to the specific thread which was
involved in the emitted event. Otherwise, it will be set to @code{None}.
@end defvar

Emits @code{gdb.ContinueEvent} which extends @code{gdb.ThreadEvent}.

This event indicates that the inferior has been continued after a stop. For
inherited attribute refer to @code{gdb.ThreadEvent} above.

@item events.exited
Emits @code{events.ExitedEvent} which indicates that the inferior has exited.
@code{events.ExitedEvent} has two attributes:
@defvar ExitedEvent.exit_code
An integer representing the exit code, if available, which the inferior 
has returned.  (The exit code could be unavailable if, for example,
@value{GDBN} detaches from the inferior.) If the exit code is unavailable,
the attribute does not exist.
@end defvar
@defvar ExitedEvent.inferior
A reference to the inferior which triggered the @code{exited} event.
@end defvar

@item events.stop
Emits @code{gdb.StopEvent} which extends @code{gdb.ThreadEvent}.

Indicates that the inferior has stopped.  All events emitted by this registry
extend StopEvent.  As a child of @code{gdb.ThreadEvent}, @code{gdb.StopEvent}
will indicate the stopped thread when @value{GDBN} is running in non-stop
mode.  Refer to @code{gdb.ThreadEvent} above for more details.

Emits @code{gdb.SignalEvent} which extends @code{gdb.StopEvent}.

This event indicates that the inferior or one of its threads has received as
signal.  @code{gdb.SignalEvent} has the following attributes:

@defvar SignalEvent.stop_signal
A string representing the signal received by the inferior.  A list of possible
signal values can be obtained by running the command @code{info signals} in
the @value{GDBN} command prompt.
@end defvar

Also emits  @code{gdb.BreakpointEvent} which extends @code{gdb.StopEvent}.

@code{gdb.BreakpointEvent} event indicates that one or more breakpoints have
been hit, and has the following attributes:

@defvar BreakpointEvent.breakpoints
A sequence containing references to all the breakpoints (type 
@code{gdb.Breakpoint}) that were hit.
@xref{Breakpoints In Python}, for details of the @code{gdb.Breakpoint} object.
@end defvar
@defvar BreakpointEvent.breakpoint
A reference to the first breakpoint that was hit.
This function is maintained for backward compatibility and is now deprecated 
in favor of the @code{gdb.BreakpointEvent.breakpoints} attribute.
@end defvar

@item events.new_objfile
Emits @code{gdb.NewObjFileEvent} which indicates that a new object file has
been loaded by @value{GDBN}.  @code{gdb.NewObjFileEvent} has one attribute:

@defvar NewObjFileEvent.new_objfile
A reference to the object file (@code{gdb.Objfile}) which has been loaded.
@xref{Objfiles In Python}, for details of the @code{gdb.Objfile} object.
@end defvar

@item events.clear_objfiles
Emits @code{gdb.ClearObjFilesEvent} which indicates that the list of object
files for a program space has been reset.
@code{gdb.ClearObjFilesEvent} has one attribute:

@defvar ClearObjFilesEvent.progspace
A reference to the program space (@code{gdb.Progspace}) whose objfile list has
been cleared.  @xref{Progspaces In Python}.
@end defvar

@item events.inferior_call
Emits events just before and after a function in the inferior is
called by @value{GDBN}.  Before an inferior call, this emits an event
of type @code{gdb.InferiorCallPreEvent}, and after an inferior call,
this emits an event of type @code{gdb.InferiorCallPostEvent}.

@table @code
@tindex gdb.InferiorCallPreEvent
@item @code{gdb.InferiorCallPreEvent}
Indicates that a function in the inferior is about to be called.

@defvar InferiorCallPreEvent.ptid
The thread in which the call will be run.
@end defvar

@defvar InferiorCallPreEvent.address
The location of the function to be called.
@end defvar

@tindex gdb.InferiorCallPostEvent
@item @code{gdb.InferiorCallPostEvent}
Indicates that a function in the inferior has just been called.

@defvar InferiorCallPostEvent.ptid
The thread in which the call was run.
@end defvar

@defvar InferiorCallPostEvent.address
The location of the function that was called.
@end defvar
@end table

@item events.memory_changed
Emits @code{gdb.MemoryChangedEvent} which indicates that the memory of the
inferior has been modified by the @value{GDBN} user, for instance via a
command like @w{@code{set *addr = value}}.  The event has the following
attributes:

@defvar MemoryChangedEvent.address
The start address of the changed region.
@end defvar

@defvar MemoryChangedEvent.length
Length in bytes of the changed region.
@end defvar

@item events.register_changed
Emits @code{gdb.RegisterChangedEvent} which indicates that a register in the
inferior has been modified by the @value{GDBN} user.

@defvar RegisterChangedEvent.frame
A gdb.Frame object representing the frame in which the register was modified.
@end defvar
@defvar RegisterChangedEvent.regnum
Denotes which register was modified.
@end defvar

@item events.breakpoint_created
This is emitted when a new breakpoint has been created.  The argument
that is passed is the new @code{gdb.Breakpoint} object.

@item events.breakpoint_modified
This is emitted when a breakpoint has been modified in some way.  The
argument that is passed is the new @code{gdb.Breakpoint} object.

@item events.breakpoint_deleted
This is emitted when a breakpoint has been deleted.  The argument that
is passed is the @code{gdb.Breakpoint} object.  When this event is
emitted, the @code{gdb.Breakpoint} object will already be in its
invalid state; that is, the @code{is_valid} method will return
@code{False}.

@item events.before_prompt
This event carries no payload.  It is emitted each time @value{GDBN}
presents a prompt to the user.

@item events.new_inferior
This is emitted when a new inferior is created.  Note that the
inferior is not necessarily running; in fact, it may not even have an
associated executable.

The event is of type @code{gdb.NewInferiorEvent}.  This has a single
attribute:

@defvar NewInferiorEvent.inferior
The new inferior, a @code{gdb.Inferior} object.
@end defvar

@item events.inferior_deleted
This is emitted when an inferior has been deleted.  Note that this is
not the same as process exit; it is notified when the inferior itself
is removed, say via @code{remove-inferiors}.

The event is of type @code{gdb.InferiorDeletedEvent}.  This has a single
attribute:

@defvar NewInferiorEvent.inferior
The inferior that is being removed, a @code{gdb.Inferior} object.
@end defvar

@item events.new_thread
This is emitted when @value{GDBN} notices a new thread.  The event is of
type @code{gdb.NewThreadEvent}, which extends @code{gdb.ThreadEvent}.
This has a single attribute:

@defvar NewThreadEvent.inferior_thread
The new thread.
@end defvar

@end table

@node Threads In Python
@subsubsection Threads In Python
@cindex threads in python

@findex gdb.InferiorThread
Python scripts can access information about, and manipulate inferior threads
controlled by @value{GDBN}, via objects of the @code{gdb.InferiorThread} class.

The following thread-related functions are available in the @code{gdb}
module:

@findex gdb.selected_thread
@defun gdb.selected_thread ()
This function returns the thread object for the selected thread.  If there
is no selected thread, this will return @code{None}.
@end defun

To get the list of threads for an inferior, use the @code{Inferior.threads()}
method.  @xref{Inferiors In Python}.

A @code{gdb.InferiorThread} object has the following attributes:

@defvar InferiorThread.name
The name of the thread.  If the user specified a name using
@code{thread name}, then this returns that name.  Otherwise, if an
OS-supplied name is available, then it is returned.  Otherwise, this
returns @code{None}.

This attribute can be assigned to.  The new value must be a string
object, which sets the new name, or @code{None}, which removes any
user-specified thread name.
@end defvar

@defvar InferiorThread.num
The per-inferior number of the thread, as assigned by GDB.
@end defvar

@defvar InferiorThread.global_num
The global ID of the thread, as assigned by GDB.  You can use this to
make Python breakpoints thread-specific, for example
(@pxref{python_breakpoint_thread,,The Breakpoint.thread attribute}).
@end defvar

@defvar InferiorThread.ptid
ID of the thread, as assigned by the operating system.  This attribute is a
tuple containing three integers.  The first is the Process ID (PID); the second
is the Lightweight Process ID (LWPID), and the third is the Thread ID (TID).
Either the LWPID or TID may be 0, which indicates that the operating system
does not  use that identifier.
@end defvar

@defvar InferiorThread.inferior
The inferior this thread belongs to.  This attribute is represented as
a @code{gdb.Inferior} object.  This attribute is not writable.
@end defvar

A @code{gdb.InferiorThread} object has the following methods:

@defun InferiorThread.is_valid ()
Returns @code{True} if the @code{gdb.InferiorThread} object is valid,
@code{False} if not.  A @code{gdb.InferiorThread} object will become
invalid if the thread exits, or the inferior that the thread belongs
is deleted.  All other @code{gdb.InferiorThread} methods will throw an
exception if it is invalid at the time the method is called.
@end defun

@defun InferiorThread.switch ()
This changes @value{GDBN}'s currently selected thread to the one represented
by this object.
@end defun

@defun InferiorThread.is_stopped ()
Return a Boolean indicating whether the thread is stopped.
@end defun

@defun InferiorThread.is_running ()
Return a Boolean indicating whether the thread is running.
@end defun

@defun InferiorThread.is_exited ()
Return a Boolean indicating whether the thread is exited.
@end defun

@defun InferiorThread.handle ()
Return the thread object's handle, represented as a Python @code{bytes}
object.  A @code{gdb.Value} representation of the handle may be
constructed via @code{gdb.Value(bufobj, type)} where @var{bufobj} is
the Python @code{bytes} representation of the handle and @var{type} is
a @code{gdb.Type} for the handle type.
@end defun

@node Recordings In Python
@subsubsection Recordings In Python
@cindex recordings in python

The following recordings-related functions
(@pxref{Process Record and Replay}) are available in the @code{gdb}
module:

@defun gdb.start_recording (@r{[}method@r{]}, @r{[}format@r{]})
Start a recording using the given @var{method} and @var{format}.  If
no @var{format} is given, the default format for the recording method
is used.  If no @var{method} is given, the default method will be used.
Returns a @code{gdb.Record} object on success.  Throw an exception on
failure.

The following strings can be passed as @var{method}:

@itemize @bullet
@item
@code{"full"}
@item
@code{"btrace"}: Possible values for @var{format}: @code{"pt"},
@code{"bts"} or leave out for default format.
@end itemize
@end defun

@defun gdb.current_recording ()
Access a currently running recording.  Return a @code{gdb.Record}
object on success.  Return @code{None} if no recording is currently
active.
@end defun

@defun gdb.stop_recording ()
Stop the current recording.  Throw an exception if no recording is
currently active.  All record objects become invalid after this call.
@end defun

A @code{gdb.Record} object has the following attributes:

@defvar Record.method
A string with the current recording method, e.g.@: @code{full} or
@code{btrace}.
@end defvar

@defvar Record.format
A string with the current recording format, e.g.@: @code{bt}, @code{pts} or
@code{None}.
@end defvar

@defvar Record.begin
A method specific instruction object representing the first instruction
in this recording.
@end defvar

@defvar Record.end
A method specific instruction object representing the current
instruction, that is not actually part of the recording.
@end defvar

@defvar Record.replay_position
The instruction representing the current replay position.  If there is
no replay active, this will be @code{None}.
@end defvar

@defvar Record.instruction_history
A list with all recorded instructions.
@end defvar

@defvar Record.function_call_history
A list with all recorded function call segments.
@end defvar

A @code{gdb.Record} object has the following methods:

@defun Record.goto (instruction)
Move the replay position to the given @var{instruction}.
@end defun

The common @code{gdb.Instruction} class that recording method specific
instruction objects inherit from, has the following attributes:

@defvar Instruction.pc
An integer representing this instruction's address.
@end defvar

@defvar Instruction.data
A buffer with the raw instruction data.  In Python 3, the return value is a
@code{memoryview} object.
@end defvar

@defvar Instruction.decoded
A human readable string with the disassembled instruction.
@end defvar

@defvar Instruction.size
The size of the instruction in bytes.
@end defvar

Additionally @code{gdb.RecordInstruction} has the following attributes:

@defvar RecordInstruction.number
An integer identifying this instruction.  @code{number} corresponds to
the numbers seen in @code{record instruction-history}
(@pxref{Process Record and Replay}).
@end defvar

@defvar RecordInstruction.sal
A @code{gdb.Symtab_and_line} object representing the associated symtab
and line of this instruction.  May be @code{None} if no debug information is
available.
@end defvar

@defvar RecordInstruction.is_speculative
A boolean indicating whether the instruction was executed speculatively.
@end defvar

If an error occured during recording or decoding a recording, this error is
represented by a @code{gdb.RecordGap} object in the instruction list.  It has
the following attributes:

@defvar RecordGap.number
An integer identifying this gap.  @code{number} corresponds to the numbers seen
in @code{record instruction-history} (@pxref{Process Record and Replay}).
@end defvar

@defvar RecordGap.error_code
A numerical representation of the reason for the gap.  The value is specific to
the current recording method.
@end defvar

@defvar RecordGap.error_string
A human readable string with the reason for the gap.
@end defvar

A @code{gdb.RecordFunctionSegment} object has the following attributes:

@defvar RecordFunctionSegment.number
An integer identifying this function segment.  @code{number} corresponds to
the numbers seen in @code{record function-call-history}
(@pxref{Process Record and Replay}).
@end defvar

@defvar RecordFunctionSegment.symbol
A @code{gdb.Symbol} object representing the associated symbol.  May be
@code{None} if no debug information is available.
@end defvar

@defvar RecordFunctionSegment.level
An integer representing the function call's stack level.  May be
@code{None} if the function call is a gap.
@end defvar

@defvar RecordFunctionSegment.instructions
A list of @code{gdb.RecordInstruction} or @code{gdb.RecordGap} objects
associated with this function call.
@end defvar

@defvar RecordFunctionSegment.up
A @code{gdb.RecordFunctionSegment} object representing the caller's
function segment.  If the call has not been recorded, this will be the
function segment to which control returns.  If neither the call nor the
return have been recorded, this will be @code{None}.
@end defvar

@defvar RecordFunctionSegment.prev
A @code{gdb.RecordFunctionSegment} object representing the previous
segment of this function call.  May be @code{None}.
@end defvar

@defvar RecordFunctionSegment.next
A @code{gdb.RecordFunctionSegment} object representing the next segment of
this function call.  May be @code{None}.
@end defvar

The following example demonstrates the usage of these objects and
functions to create a function that will rewind a record to the last
time a function in a different file was executed.  This would typically
be used to track the execution of user provided callback functions in a
library which typically are not visible in a back trace.

@smallexample
def bringback ():
    rec = gdb.current_recording ()
    if not rec:
        return

    insn = rec.instruction_history
    if len (insn) == 0:
        return

    try:
        position = insn.index (rec.replay_position)
    except:
        position = -1
    try:
        filename = insn[position].sal.symtab.fullname ()
    except:
        filename = None

    for i in reversed (insn[:position]):
	try:
            current = i.sal.symtab.fullname ()
	except:
            current = None

        if filename == current:
            continue

        rec.goto (i)
        return
@end smallexample

Another possible application is to write a function that counts the
number of code executions in a given line range.  This line range can
contain parts of functions or span across several functions and is not
limited to be contiguous.

@smallexample
def countrange (filename, linerange):
    count = 0

    def filter_only (file_name):
        for call in gdb.current_recording ().function_call_history:
            try:
                if file_name in call.symbol.symtab.fullname ():
                    yield call
            except:
                pass

    for c in filter_only (filename):
        for i in c.instructions:
            try:
                if i.sal.line in linerange:
                    count += 1
                    break;
            except:
                    pass

    return count
@end smallexample

@node Commands In Python
@subsubsection Commands In Python

@cindex commands in python
@cindex python commands
You can implement new @value{GDBN} CLI commands in Python.  A CLI
command is implemented using an instance of the @code{gdb.Command}
class, most commonly using a subclass.

@defun Command.__init__ (name, @var{command_class} @r{[}, @var{completer_class} @r{[}, @var{prefix}@r{]]})
The object initializer for @code{Command} registers the new command
with @value{GDBN}.  This initializer is normally invoked from the
subclass' own @code{__init__} method.

@var{name} is the name of the command.  If @var{name} consists of
multiple words, then the initial words are looked for as prefix
commands.  In this case, if one of the prefix commands does not exist,
an exception is raised.

There is no support for multi-line commands.

@var{command_class} should be one of the @samp{COMMAND_} constants
defined below.  This argument tells @value{GDBN} how to categorize the
new command in the help system.

@var{completer_class} is an optional argument.  If given, it should be
one of the @samp{COMPLETE_} constants defined below.  This argument
tells @value{GDBN} how to perform completion for this command.  If not
given, @value{GDBN} will attempt to complete using the object's
@code{complete} method (see below); if no such method is found, an
error will occur when completion is attempted.

@var{prefix} is an optional argument.  If @code{True}, then the new
command is a prefix command; sub-commands of this command may be
registered.

The help text for the new command is taken from the Python
documentation string for the command's class, if there is one.  If no
documentation string is provided, the default value ``This command is
not documented.'' is used.
@end defun

@cindex don't repeat Python command
@defun Command.dont_repeat ()
By default, a @value{GDBN} command is repeated when the user enters a
blank line at the command prompt.  A command can suppress this
behavior by invoking the @code{dont_repeat} method.  This is similar
to the user command @code{dont-repeat}, see @ref{Define, dont-repeat}.
@end defun

@defun Command.invoke (argument, from_tty)
This method is called by @value{GDBN} when this command is invoked.

@var{argument} is a string.  It is the argument to the command, after
leading and trailing whitespace has been stripped.

@var{from_tty} is a boolean argument.  When true, this means that the
command was entered by the user at the terminal; when false it means
that the command came from elsewhere.

If this method throws an exception, it is turned into a @value{GDBN}
@code{error} call.  Otherwise, the return value is ignored.

@findex gdb.string_to_argv
To break @var{argument} up into an argv-like string use
@code{gdb.string_to_argv}.  This function behaves identically to
@value{GDBN}'s internal argument lexer @code{buildargv}.
It is recommended to use this for consistency.
Arguments are separated by spaces and may be quoted.
Example:

@smallexample
print gdb.string_to_argv ("1 2\ \\\"3 '4 \"5' \"6 '7\"")
['1', '2 "3', '4 "5', "6 '7"]
@end smallexample

@end defun

@cindex completion of Python commands
@defun Command.complete (text, word)
This method is called by @value{GDBN} when the user attempts
completion on this command.  All forms of completion are handled by
this method, that is, the @key{TAB} and @key{M-?} key bindings
(@pxref{Completion}), and the @code{complete} command (@pxref{Help,
complete}).

The arguments @var{text} and @var{word} are both strings; @var{text}
holds the complete command line up to the cursor's location, while
@var{word} holds the last word of the command line; this is computed
using a word-breaking heuristic.

The @code{complete} method can return several values:
@itemize @bullet
@item
If the return value is a sequence, the contents of the sequence are
used as the completions.  It is up to @code{complete} to ensure that the
contents actually do complete the word.  A zero-length sequence is
allowed, it means that there were no completions available.  Only
string elements of the sequence are used; other elements in the
sequence are ignored.

@item
If the return value is one of the @samp{COMPLETE_} constants defined
below, then the corresponding @value{GDBN}-internal completion
function is invoked, and its result is used.

@item
All other results are treated as though there were no available
completions.
@end itemize
@end defun

When a new command is registered, it must be declared as a member of
some general class of commands.  This is used to classify top-level
commands in the on-line help system; note that prefix commands are not
listed under their own category but rather that of their top-level
command.  The available classifications are represented by constants
defined in the @code{gdb} module:

@table @code
@findex COMMAND_NONE
@findex gdb.COMMAND_NONE
@item gdb.COMMAND_NONE
The command does not belong to any particular class.  A command in
this category will not be displayed in any of the help categories.

@findex COMMAND_RUNNING
@findex gdb.COMMAND_RUNNING
@item gdb.COMMAND_RUNNING
The command is related to running the inferior.  For example,
@code{start}, @code{step}, and @code{continue} are in this category.
Type @kbd{help running} at the @value{GDBN} prompt to see a list of
commands in this category.

@findex COMMAND_DATA
@findex gdb.COMMAND_DATA
@item gdb.COMMAND_DATA
The command is related to data or variables.  For example,
@code{call}, @code{find}, and @code{print} are in this category.  Type
@kbd{help data} at the @value{GDBN} prompt to see a list of commands
in this category.

@findex COMMAND_STACK
@findex gdb.COMMAND_STACK
@item gdb.COMMAND_STACK
The command has to do with manipulation of the stack.  For example,
@code{backtrace}, @code{frame}, and @code{return} are in this
category.  Type @kbd{help stack} at the @value{GDBN} prompt to see a
list of commands in this category.

@findex COMMAND_FILES
@findex gdb.COMMAND_FILES
@item gdb.COMMAND_FILES
This class is used for file-related commands.  For example,
@code{file}, @code{list} and @code{section} are in this category.
Type @kbd{help files} at the @value{GDBN} prompt to see a list of
commands in this category.

@findex COMMAND_SUPPORT
@findex gdb.COMMAND_SUPPORT
@item gdb.COMMAND_SUPPORT
This should be used for ``support facilities'', generally meaning
things that are useful to the user when interacting with @value{GDBN},
but not related to the state of the inferior.  For example,
@code{help}, @code{make}, and @code{shell} are in this category.  Type
@kbd{help support} at the @value{GDBN} prompt to see a list of
commands in this category.

@findex COMMAND_STATUS
@findex gdb.COMMAND_STATUS
@item gdb.COMMAND_STATUS
The command is an @samp{info}-related command, that is, related to the
state of @value{GDBN} itself.  For example, @code{info}, @code{macro},
and @code{show} are in this category.  Type @kbd{help status} at the
@value{GDBN} prompt to see a list of commands in this category.

@findex COMMAND_BREAKPOINTS
@findex gdb.COMMAND_BREAKPOINTS
@item gdb.COMMAND_BREAKPOINTS
The command has to do with breakpoints.  For example, @code{break},
@code{clear}, and @code{delete} are in this category.  Type @kbd{help
breakpoints} at the @value{GDBN} prompt to see a list of commands in
this category.

@findex COMMAND_TRACEPOINTS
@findex gdb.COMMAND_TRACEPOINTS
@item gdb.COMMAND_TRACEPOINTS
The command has to do with tracepoints.  For example, @code{trace},
@code{actions}, and @code{tfind} are in this category.  Type
@kbd{help tracepoints} at the @value{GDBN} prompt to see a list of
commands in this category.

@findex COMMAND_TUI
@findex gdb.COMMAND_TUI
@item gdb.COMMAND_TUI
The command has to do with the text user interface (@pxref{TUI}).
Type @kbd{help tui} at the @value{GDBN} prompt to see a list of
commands in this category.

@findex COMMAND_USER
@findex gdb.COMMAND_USER
@item gdb.COMMAND_USER
The command is a general purpose command for the user, and typically
does not fit in one of the other categories.
Type @kbd{help user-defined} at the @value{GDBN} prompt to see
a list of commands in this category, as well as the list of gdb macros
(@pxref{Sequences}).

@findex COMMAND_OBSCURE
@findex gdb.COMMAND_OBSCURE
@item gdb.COMMAND_OBSCURE
The command is only used in unusual circumstances, or is not of
general interest to users.  For example, @code{checkpoint},
@code{fork}, and @code{stop} are in this category.  Type @kbd{help
obscure} at the @value{GDBN} prompt to see a list of commands in this
category.

@findex COMMAND_MAINTENANCE
@findex gdb.COMMAND_MAINTENANCE
@item gdb.COMMAND_MAINTENANCE
The command is only useful to @value{GDBN} maintainers.  The
@code{maintenance} and @code{flushregs} commands are in this category.
Type @kbd{help internals} at the @value{GDBN} prompt to see a list of
commands in this category.
@end table

A new command can use a predefined completion function, either by
specifying it via an argument at initialization, or by returning it
from the @code{complete} method.  These predefined completion
constants are all defined in the @code{gdb} module:

@vtable @code
@vindex COMPLETE_NONE
@item gdb.COMPLETE_NONE
This constant means that no completion should be done.

@vindex COMPLETE_FILENAME
@item gdb.COMPLETE_FILENAME
This constant means that filename completion should be performed.

@vindex COMPLETE_LOCATION
@item gdb.COMPLETE_LOCATION
This constant means that location completion should be done.
@xref{Specify Location}.

@vindex COMPLETE_COMMAND
@item gdb.COMPLETE_COMMAND
This constant means that completion should examine @value{GDBN}
command names.

@vindex COMPLETE_SYMBOL
@item gdb.COMPLETE_SYMBOL
This constant means that completion should be done using symbol names
as the source.

@vindex COMPLETE_EXPRESSION
@item gdb.COMPLETE_EXPRESSION
This constant means that completion should be done on expressions.
Often this means completing on symbol names, but some language
parsers also have support for completing on field names.
@end vtable

The following code snippet shows how a trivial CLI command can be
implemented in Python:

@smallexample
class HelloWorld (gdb.Command):
  """Greet the whole world."""

  def __init__ (self):
    super (HelloWorld, self).__init__ ("hello-world", gdb.COMMAND_USER)

  def invoke (self, arg, from_tty):
    print ("Hello, World!")

HelloWorld ()
@end smallexample

The last line instantiates the class, and is necessary to trigger the
registration of the command with @value{GDBN}.  Depending on how the
Python code is read into @value{GDBN}, you may need to import the
@code{gdb} module explicitly.

@node Parameters In Python
@subsubsection Parameters In Python

@cindex parameters in python
@cindex python parameters
@tindex gdb.Parameter
@tindex Parameter
You can implement new @value{GDBN} parameters using Python.  A new
parameter is implemented as an instance of the @code{gdb.Parameter}
class.

Parameters are exposed to the user via the @code{set} and
@code{show} commands.  @xref{Help}.

There are many parameters that already exist and can be set in
@value{GDBN}.  Two examples are: @code{set follow fork} and
@code{set charset}.  Setting these parameters influences certain
behavior in @value{GDBN}.  Similarly, you can define parameters that
can be used to influence behavior in custom Python scripts and commands.

@defun Parameter.__init__ (name, @var{command-class}, @var{parameter-class} @r{[}, @var{enum-sequence}@r{]})
The object initializer for @code{Parameter} registers the new
parameter with @value{GDBN}.  This initializer is normally invoked
from the subclass' own @code{__init__} method.

@var{name} is the name of the new parameter.  If @var{name} consists
of multiple words, then the initial words are looked for as prefix
parameters.  An example of this can be illustrated with the
@code{set print} set of parameters.  If @var{name} is
@code{print foo}, then @code{print} will be searched as the prefix
parameter.  In this case the parameter can subsequently be accessed in
@value{GDBN} as @code{set print foo}.

If @var{name} consists of multiple words, and no prefix parameter group
can be found, an exception is raised.

@var{command-class} should be one of the @samp{COMMAND_} constants
(@pxref{Commands In Python}).  This argument tells @value{GDBN} how to
categorize the new parameter in the help system.

@var{parameter-class} should be one of the @samp{PARAM_} constants
defined below.  This argument tells @value{GDBN} the type of the new
parameter; this information is used for input validation and
completion.

If @var{parameter-class} is @code{PARAM_ENUM}, then
@var{enum-sequence} must be a sequence of strings.  These strings
represent the possible values for the parameter.

If @var{parameter-class} is not @code{PARAM_ENUM}, then the presence
of a fourth argument will cause an exception to be thrown.

The help text for the new parameter is taken from the Python
documentation string for the parameter's class, if there is one.  If
there is no documentation string, a default value is used.
@end defun

@defvar Parameter.set_doc
If this attribute exists, and is a string, then its value is used as
the help text for this parameter's @code{set} command.  The value is
examined when @code{Parameter.__init__} is invoked; subsequent changes
have no effect.
@end defvar

@defvar Parameter.show_doc
If this attribute exists, and is a string, then its value is used as
the help text for this parameter's @code{show} command.  The value is
examined when @code{Parameter.__init__} is invoked; subsequent changes
have no effect.
@end defvar

@defvar Parameter.value
The @code{value} attribute holds the underlying value of the
parameter.  It can be read and assigned to just as any other
attribute.  @value{GDBN} does validation when assignments are made.
@end defvar

There are two methods that may be implemented in any @code{Parameter}
class.  These are:

@defun Parameter.get_set_string (self)
If this method exists, @value{GDBN} will call it when a
@var{parameter}'s value has been changed via the @code{set} API (for
example, @kbd{set foo off}).  The @code{value} attribute has already
been populated with the new value and may be used in output.  This
method must return a string.  If the returned string is not empty,
@value{GDBN} will present it to the user.

If this method raises the @code{gdb.GdbError} exception
(@pxref{Exception Handling}), then @value{GDBN} will print the
exception's string and the @code{set} command will fail.  Note,
however, that the @code{value} attribute will not be reset in this
case.  So, if your parameter must validate values, it should store the
old value internally and reset the exposed value, like so:

@smallexample
class ExampleParam (gdb.Parameter):
   def __init__ (self, name):
      super (ExampleParam, self).__init__ (name,
                   gdb.COMMAND_DATA,
                   gdb.PARAM_BOOLEAN)
      self.value = True
      self.saved_value = True
   def validate(self):
      return False
   def get_set_string (self):
      if not self.validate():
        self.value = self.saved_value
        raise gdb.GdbError('Failed to validate')
      self.saved_value = self.value
      return ""
@end smallexample
@end defun

@defun Parameter.get_show_string (self, svalue)
@value{GDBN} will call this method when a @var{parameter}'s
@code{show} API has been invoked (for example, @kbd{show foo}).  The
argument @code{svalue} receives the string representation of the
current value.  This method must return a string.
@end defun

When a new parameter is defined, its type must be specified.  The
available types are represented by constants defined in the @code{gdb}
module:

@table @code
@findex PARAM_BOOLEAN
@findex gdb.PARAM_BOOLEAN
@item gdb.PARAM_BOOLEAN
The value is a plain boolean.  The Python boolean values, @code{True}
and @code{False} are the only valid values.

@findex PARAM_AUTO_BOOLEAN
@findex gdb.PARAM_AUTO_BOOLEAN
@item gdb.PARAM_AUTO_BOOLEAN
The value has three possible states: true, false, and @samp{auto}.  In
Python, true and false are represented using boolean constants, and
@samp{auto} is represented using @code{None}.

@findex PARAM_UINTEGER
@findex gdb.PARAM_UINTEGER
@item gdb.PARAM_UINTEGER
The value is an unsigned integer.  The value of 0 should be
interpreted to mean ``unlimited''.

@findex PARAM_INTEGER
@findex gdb.PARAM_INTEGER
@item gdb.PARAM_INTEGER
The value is a signed integer.  The value of 0 should be interpreted
to mean ``unlimited''.

@findex PARAM_STRING
@findex gdb.PARAM_STRING
@item gdb.PARAM_STRING
The value is a string.  When the user modifies the string, any escape
sequences, such as @samp{\t}, @samp{\f}, and octal escapes, are
translated into corresponding characters and encoded into the current
host charset.

@findex PARAM_STRING_NOESCAPE
@findex gdb.PARAM_STRING_NOESCAPE
@item gdb.PARAM_STRING_NOESCAPE
The value is a string.  When the user modifies the string, escapes are
passed through untranslated.

@findex PARAM_OPTIONAL_FILENAME
@findex gdb.PARAM_OPTIONAL_FILENAME
@item gdb.PARAM_OPTIONAL_FILENAME
The value is a either a filename (a string), or @code{None}.

@findex PARAM_FILENAME
@findex gdb.PARAM_FILENAME
@item gdb.PARAM_FILENAME
The value is a filename.  This is just like
@code{PARAM_STRING_NOESCAPE}, but uses file names for completion.

@findex PARAM_ZINTEGER
@findex gdb.PARAM_ZINTEGER
@item gdb.PARAM_ZINTEGER
The value is an integer.  This is like @code{PARAM_INTEGER}, except 0
is interpreted as itself.

@findex PARAM_ZUINTEGER
@findex gdb.PARAM_ZUINTEGER
@item gdb.PARAM_ZUINTEGER
The value is an unsigned integer.  This is like @code{PARAM_INTEGER},
except 0 is interpreted as itself, and the value cannot be negative.

@findex PARAM_ZUINTEGER_UNLIMITED
@findex gdb.PARAM_ZUINTEGER_UNLIMITED
@item gdb.PARAM_ZUINTEGER_UNLIMITED
The value is a signed integer.  This is like @code{PARAM_ZUINTEGER},
except the special value -1 should be interpreted to mean
``unlimited''.  Other negative values are not allowed.

@findex PARAM_ENUM
@findex gdb.PARAM_ENUM
@item gdb.PARAM_ENUM
The value is a string, which must be one of a collection string
constants provided when the parameter is created.
@end table

@node Functions In Python
@subsubsection Writing new convenience functions

@cindex writing convenience functions
@cindex convenience functions in python
@cindex python convenience functions
@tindex gdb.Function
@tindex Function
You can implement new convenience functions (@pxref{Convenience Vars})
in Python.  A convenience function is an instance of a subclass of the
class @code{gdb.Function}.

@defun Function.__init__ (name)
The initializer for @code{Function} registers the new function with
@value{GDBN}.  The argument @var{name} is the name of the function,
a string.  The function will be visible to the user as a convenience
variable of type @code{internal function}, whose name is the same as
the given @var{name}.

The documentation for the new function is taken from the documentation
string for the new class.
@end defun

@defun Function.invoke (@var{*args})
When a convenience function is evaluated, its arguments are converted
to instances of @code{gdb.Value}, and then the function's
@code{invoke} method is called.  Note that @value{GDBN} does not
predetermine the arity of convenience functions.  Instead, all
available arguments are passed to @code{invoke}, following the
standard Python calling convention.  In particular, a convenience
function can have default values for parameters without ill effect.

The return value of this method is used as its value in the enclosing
expression.  If an ordinary Python value is returned, it is converted
to a @code{gdb.Value} following the usual rules.
@end defun

The following code snippet shows how a trivial convenience function can
be implemented in Python:

@smallexample
class Greet (gdb.Function):
  """Return string to greet someone.
Takes a name as argument."""

  def __init__ (self):
    super (Greet, self).__init__ ("greet")

  def invoke (self, name):
    return "Hello, %s!" % name.string ()

Greet ()
@end smallexample

The last line instantiates the class, and is necessary to trigger the
registration of the function with @value{GDBN}.  Depending on how the
Python code is read into @value{GDBN}, you may need to import the
@code{gdb} module explicitly.

Now you can use the function in an expression:

@smallexample
(gdb) print $greet("Bob")
$1 = "Hello, Bob!"
@end smallexample

@node Progspaces In Python
@subsubsection Program Spaces In Python

@cindex progspaces in python
@tindex gdb.Progspace
@tindex Progspace
A program space, or @dfn{progspace}, represents a symbolic view
of an address space.
It consists of all of the objfiles of the program.
@xref{Objfiles In Python}.
@xref{Inferiors Connections and Programs, program spaces}, for more details
about program spaces.

The following progspace-related functions are available in the
@code{gdb} module:

@findex gdb.current_progspace
@defun gdb.current_progspace ()
This function returns the program space of the currently selected inferior.
@xref{Inferiors Connections and Programs}.  This is identical to
@code{gdb.selected_inferior().progspace} (@pxref{Inferiors In Python}) and is
included for historical compatibility.
@end defun

@findex gdb.progspaces
@defun gdb.progspaces ()
Return a sequence of all the progspaces currently known to @value{GDBN}.
@end defun

Each progspace is represented by an instance of the @code{gdb.Progspace}
class.

@defvar Progspace.filename
The file name of the progspace as a string.
@end defvar

@defvar Progspace.pretty_printers
The @code{pretty_printers} attribute is a list of functions.  It is
used to look up pretty-printers.  A @code{Value} is passed to each
function in order; if the function returns @code{None}, then the
search continues.  Otherwise, the return value should be an object
which is used to format the value.  @xref{Pretty Printing API}, for more
information.
@end defvar

@defvar Progspace.type_printers
The @code{type_printers} attribute is a list of type printer objects.
@xref{Type Printing API}, for more information.
@end defvar

@defvar Progspace.frame_filters
The @code{frame_filters} attribute is a dictionary of frame filter
objects.  @xref{Frame Filter API}, for more information.
@end defvar

A program space has the following methods:

@findex Progspace.block_for_pc
@defun Progspace.block_for_pc (pc)
Return the innermost @code{gdb.Block} containing the given @var{pc}
value.  If the block cannot be found for the @var{pc} value specified,
the function will return @code{None}.
@end defun

@findex Progspace.find_pc_line
@defun Progspace.find_pc_line (pc)
Return the @code{gdb.Symtab_and_line} object corresponding to the
@var{pc} value.  @xref{Symbol Tables In Python}.  If an invalid value
of @var{pc} is passed as an argument, then the @code{symtab} and
@code{line} attributes of the returned @code{gdb.Symtab_and_line}
object will be @code{None} and 0 respectively.
@end defun

@findex Progspace.is_valid
@defun Progspace.is_valid ()
Returns @code{True} if the @code{gdb.Progspace} object is valid,
@code{False} if not.  A @code{gdb.Progspace} object can become invalid
if the program space file it refers to is not referenced by any
inferior.  All other @code{gdb.Progspace} methods will throw an
exception if it is invalid at the time the method is called.
@end defun

@findex Progspace.objfiles
@defun Progspace.objfiles ()
Return a sequence of all the objfiles referenced by this program
space.  @xref{Objfiles In Python}.
@end defun

@findex Progspace.solib_name
@defun Progspace.solib_name (address)
Return the name of the shared library holding the given @var{address}
as a string, or @code{None}.
@end defun

One may add arbitrary attributes to @code{gdb.Progspace} objects
in the usual Python way.
This is useful if, for example, one needs to do some extra record keeping
associated with the program space.

In this contrived example, we want to perform some processing when
an objfile with a certain symbol is loaded, but we only want to do
this once because it is expensive.  To achieve this we record the results
with the program space because we can't predict when the desired objfile
will be loaded.

@smallexample
(gdb) python
def clear_objfiles_handler(event):
    event.progspace.expensive_computation = None
def expensive(symbol):
    """A mock routine to perform an "expensive" computation on symbol."""
    print ("Computing the answer to the ultimate question ...")
    return 42
def new_objfile_handler(event):
    objfile = event.new_objfile
    progspace = objfile.progspace
    if not hasattr(progspace, 'expensive_computation') or \
            progspace.expensive_computation is None:
        # We use 'main' for the symbol to keep the example simple.
        # Note: There's no current way to constrain the lookup
        # to one objfile.
        symbol = gdb.lookup_global_symbol('main')
        if symbol is not None:
            progspace.expensive_computation = expensive(symbol)
gdb.events.clear_objfiles.connect(clear_objfiles_handler)
gdb.events.new_objfile.connect(new_objfile_handler)
end
(gdb) file /tmp/hello
Reading symbols from /tmp/hello...
Computing the answer to the ultimate question ...
(gdb) python print gdb.current_progspace().expensive_computation
42
(gdb) run
Starting program: /tmp/hello
Hello.
[Inferior 1 (process 4242) exited normally]
@end smallexample

@node Objfiles In Python
@subsubsection Objfiles In Python

@cindex objfiles in python
@tindex gdb.Objfile
@tindex Objfile
@value{GDBN} loads symbols for an inferior from various
symbol-containing files (@pxref{Files}).  These include the primary
executable file, any shared libraries used by the inferior, and any
separate debug info files (@pxref{Separate Debug Files}).
@value{GDBN} calls these symbol-containing files @dfn{objfiles}.

The following objfile-related functions are available in the
@code{gdb} module:

@findex gdb.current_objfile
@defun gdb.current_objfile ()
When auto-loading a Python script (@pxref{Python Auto-loading}), @value{GDBN}
sets the ``current objfile'' to the corresponding objfile.  This
function returns the current objfile.  If there is no current objfile,
this function returns @code{None}.
@end defun

@findex gdb.objfiles
@defun gdb.objfiles ()
Return a sequence of objfiles referenced by the current program space.
@xref{Objfiles In Python}, and @ref{Progspaces In Python}.  This is identical
to @code{gdb.selected_inferior().progspace.objfiles()} and is included for
historical compatibility.
@end defun

@findex gdb.lookup_objfile
@defun gdb.lookup_objfile (name @r{[}, by_build_id{]})
Look up @var{name}, a file name or build ID, in the list of objfiles
for the current program space (@pxref{Progspaces In Python}).
If the objfile is not found throw the Python @code{ValueError} exception.

If @var{name} is a relative file name, then it will match any
source file name with the same trailing components.  For example, if
@var{name} is @samp{gcc/expr.c}, then it will match source file
name of @file{/build/trunk/gcc/expr.c}, but not
@file{/build/trunk/libcpp/expr.c} or @file{/build/trunk/gcc/x-expr.c}.

If @var{by_build_id} is provided and is @code{True} then @var{name}
is the build ID of the objfile.  Otherwise, @var{name} is a file name.
This is supported only on some operating systems, notably those which use
the ELF format for binary files and the @sc{gnu} Binutils.  For more details
about this feature, see the description of the @option{--build-id}
command-line option in @ref{Options, , Command Line Options, ld,
The GNU Linker}.
@end defun

Each objfile is represented by an instance of the @code{gdb.Objfile}
class.

@defvar Objfile.filename
The file name of the objfile as a string, with symbolic links resolved.

The value is @code{None} if the objfile is no longer valid.
See the @code{gdb.Objfile.is_valid} method, described below.
@end defvar

@defvar Objfile.username
The file name of the objfile as specified by the user as a string.

The value is @code{None} if the objfile is no longer valid.
See the @code{gdb.Objfile.is_valid} method, described below.
@end defvar

@defvar Objfile.owner
For separate debug info objfiles this is the corresponding @code{gdb.Objfile}
object that debug info is being provided for.
Otherwise this is @code{None}.
Separate debug info objfiles are added with the
@code{gdb.Objfile.add_separate_debug_file} method, described below.
@end defvar

@defvar Objfile.build_id
The build ID of the objfile as a string.
If the objfile does not have a build ID then the value is @code{None}.

This is supported only on some operating systems, notably those which use
the ELF format for binary files and the @sc{gnu} Binutils.  For more details
about this feature, see the description of the @option{--build-id}
command-line option in @ref{Options, , Command Line Options, ld,
The GNU Linker}.
@end defvar

@defvar Objfile.progspace
The containing program space of the objfile as a @code{gdb.Progspace}
object.  @xref{Progspaces In Python}.
@end defvar

@defvar Objfile.pretty_printers
The @code{pretty_printers} attribute is a list of functions.  It is
used to look up pretty-printers.  A @code{Value} is passed to each
function in order; if the function returns @code{None}, then the
search continues.  Otherwise, the return value should be an object
which is used to format the value.  @xref{Pretty Printing API}, for more
information.
@end defvar

@defvar Objfile.type_printers
The @code{type_printers} attribute is a list of type printer objects.
@xref{Type Printing API}, for more information.
@end defvar

@defvar Objfile.frame_filters
The @code{frame_filters} attribute is a dictionary of frame filter
objects.  @xref{Frame Filter API}, for more information.
@end defvar

One may add arbitrary attributes to @code{gdb.Objfile} objects
in the usual Python way.
This is useful if, for example, one needs to do some extra record keeping
associated with the objfile.

In this contrived example we record the time when @value{GDBN}
loaded the objfile.

@smallexample
(gdb) python
import datetime
def new_objfile_handler(event):
    # Set the time_loaded attribute of the new objfile.
    event.new_objfile.time_loaded = datetime.datetime.today()
gdb.events.new_objfile.connect(new_objfile_handler)
end
(gdb) file ./hello
Reading symbols from ./hello...
(gdb) python print gdb.objfiles()[0].time_loaded
2014-10-09 11:41:36.770345
@end smallexample

A @code{gdb.Objfile} object has the following methods:

@defun Objfile.is_valid ()
Returns @code{True} if the @code{gdb.Objfile} object is valid,
@code{False} if not.  A @code{gdb.Objfile} object can become invalid
if the object file it refers to is not loaded in @value{GDBN} any
longer.  All other @code{gdb.Objfile} methods will throw an exception
if it is invalid at the time the method is called.
@end defun

@defun Objfile.add_separate_debug_file (file)
Add @var{file} to the list of files that @value{GDBN} will search for
debug information for the objfile.
This is useful when the debug info has been removed from the program
and stored in a separate file.  @value{GDBN} has built-in support for
finding separate debug info files (@pxref{Separate Debug Files}), but if
the file doesn't live in one of the standard places that @value{GDBN}
searches then this function can be used to add a debug info file
from a different place.
@end defun

@defun Objfile.lookup_global_symbol (name @r{[}, domain@r{]})
Search for a global symbol named @var{name} in this objfile.  Optionally, the
search scope can be restricted with the @var{domain} argument.
The @var{domain} argument must be a domain constant defined in the @code{gdb}
module and described in @ref{Symbols In Python}.  This function is similar to
@code{gdb.lookup_global_symbol}, except that the search is limited to this
objfile.

The result is a @code{gdb.Symbol} object or @code{None} if the symbol
is not found.
@end defun

@defun Objfile.lookup_static_symbol (name @r{[}, domain@r{]})
Like @code{Objfile.lookup_global_symbol}, but searches for a global
symbol with static linkage named @var{name} in this objfile.
@end defun

@node Frames In Python
@subsubsection Accessing inferior stack frames from Python

@cindex frames in python
When the debugged program stops, @value{GDBN} is able to analyze its call
stack (@pxref{Frames,,Stack frames}).  The @code{gdb.Frame} class
represents a frame in the stack.  A @code{gdb.Frame} object is only valid
while its corresponding frame exists in the inferior's stack.  If you try
to use an invalid frame object, @value{GDBN} will throw a @code{gdb.error}
exception (@pxref{Exception Handling}).

Two @code{gdb.Frame} objects can be compared for equality with the @code{==}
operator, like:

@smallexample
(@value{GDBP}) python print gdb.newest_frame() == gdb.selected_frame ()
True
@end smallexample

The following frame-related functions are available in the @code{gdb} module:

@findex gdb.selected_frame
@defun gdb.selected_frame ()
Return the selected frame object.  (@pxref{Selection,,Selecting a Frame}).
@end defun

@findex gdb.newest_frame
@defun gdb.newest_frame ()
Return the newest frame object for the selected thread.
@end defun

@defun gdb.frame_stop_reason_string (reason)
Return a string explaining the reason why @value{GDBN} stopped unwinding
frames, as expressed by the given @var{reason} code (an integer, see the
@code{unwind_stop_reason} method further down in this section).
@end defun

@findex gdb.invalidate_cached_frames
@defun gdb.invalidate_cached_frames
@value{GDBN} internally keeps a cache of the frames that have been
unwound.  This function invalidates this cache.

This function should not generally be called by ordinary Python code.
It is documented for the sake of completeness.
@end defun

A @code{gdb.Frame} object has the following methods:

@defun Frame.is_valid ()
Returns true if the @code{gdb.Frame} object is valid, false if not.
A frame object can become invalid if the frame it refers to doesn't
exist anymore in the inferior.  All @code{gdb.Frame} methods will throw
an exception if it is invalid at the time the method is called.
@end defun

@defun Frame.name ()
Returns the function name of the frame, or @code{None} if it can't be
obtained.
@end defun

@defun Frame.architecture ()
Returns the @code{gdb.Architecture} object corresponding to the frame's
architecture.  @xref{Architectures In Python}.
@end defun

@defun Frame.type ()
Returns the type of the frame.  The value can be one of:
@table @code
@item gdb.NORMAL_FRAME
An ordinary stack frame.

@item gdb.DUMMY_FRAME
A fake stack frame that was created by @value{GDBN} when performing an
inferior function call.

@item gdb.INLINE_FRAME
A frame representing an inlined function.  The function was inlined
into a @code{gdb.NORMAL_FRAME} that is older than this one.

@item gdb.TAILCALL_FRAME
A frame representing a tail call.  @xref{Tail Call Frames}.

@item gdb.SIGTRAMP_FRAME
A signal trampoline frame.  This is the frame created by the OS when
it calls into a signal handler.

@item gdb.ARCH_FRAME
A fake stack frame representing a cross-architecture call.

@item gdb.SENTINEL_FRAME
This is like @code{gdb.NORMAL_FRAME}, but it is only used for the
newest frame.
@end table
@end defun

@defun Frame.unwind_stop_reason ()
Return an integer representing the reason why it's not possible to find
more frames toward the outermost frame.  Use
@code{gdb.frame_stop_reason_string} to convert the value returned by this
function to a string. The value can be one of:

@table @code
@item gdb.FRAME_UNWIND_NO_REASON
No particular reason (older frames should be available).

@item gdb.FRAME_UNWIND_NULL_ID
The previous frame's analyzer returns an invalid result.  This is no
longer used by @value{GDBN}, and is kept only for backward
compatibility.

@item gdb.FRAME_UNWIND_OUTERMOST
This frame is the outermost.

@item gdb.FRAME_UNWIND_UNAVAILABLE
Cannot unwind further, because that would require knowing the 
values of registers or memory that have not been collected.

@item gdb.FRAME_UNWIND_INNER_ID
This frame ID looks like it ought to belong to a NEXT frame,
but we got it for a PREV frame.  Normally, this is a sign of
unwinder failure.  It could also indicate stack corruption.

@item gdb.FRAME_UNWIND_SAME_ID
This frame has the same ID as the previous one.  That means
that unwinding further would almost certainly give us another
frame with exactly the same ID, so break the chain.  Normally,
this is a sign of unwinder failure.  It could also indicate
stack corruption.

@item gdb.FRAME_UNWIND_NO_SAVED_PC
The frame unwinder did not find any saved PC, but we needed
one to unwind further.

@item gdb.FRAME_UNWIND_MEMORY_ERROR
The frame unwinder caused an error while trying to access memory.

@item gdb.FRAME_UNWIND_FIRST_ERROR
Any stop reason greater or equal to this value indicates some kind
of error.  This special value facilitates writing code that tests
for errors in unwinding in a way that will work correctly even if
the list of the other values is modified in future @value{GDBN}
versions.  Using it, you could write:
@smallexample
reason = gdb.selected_frame().unwind_stop_reason ()
reason_str =  gdb.frame_stop_reason_string (reason)
if reason >=  gdb.FRAME_UNWIND_FIRST_ERROR:
    print ("An error occured: %s" % reason_str)
@end smallexample
@end table

@end defun

@defun Frame.pc ()
Returns the frame's resume address.
@end defun

@defun Frame.block ()
Return the frame's code block.  @xref{Blocks In Python}.  If the frame
does not have a block -- for example, if there is no debugging
information for the code in question -- then this will throw an
exception.
@end defun

@defun Frame.function ()
Return the symbol for the function corresponding to this frame.
@xref{Symbols In Python}.
@end defun

@defun Frame.older ()
Return the frame that called this frame.
@end defun

@defun Frame.newer ()
Return the frame called by this frame.
@end defun

@defun Frame.find_sal ()
Return the frame's symtab and line object.
@xref{Symbol Tables In Python}.
@end defun

@anchor{gdbpy_frame_read_register}
@defun Frame.read_register (register)
Return the value of @var{register} in this frame.  Returns a
@code{Gdb.Value} object.  Throws an exception if @var{register} does
not exist.  The @var{register} argument must be one of the following:
@enumerate
@item
A string that is the name of a valid register (e.g., @code{'sp'} or
@code{'rax'}).
@item
A @code{gdb.RegisterDescriptor} object (@pxref{Registers In Python}).
@item
A @value{GDBN} internal, platform specific number.  Using these
numbers is supported for historic reasons, but is not recommended as
future changes to @value{GDBN} could change the mapping between
numbers and the registers they represent, breaking any Python code
that uses the platform-specific numbers.  The numbers are usually
found in the corresponding @file{@var{platform}-tdep.h} file in the
@value{GDBN} source tree.
@end enumerate
Using a string to access registers will be slightly slower than the
other two methods as @value{GDBN} must look up the mapping between
name and internal register number.  If performance is critical
consider looking up and caching a @code{gdb.RegisterDescriptor}
object.
@end defun

@defun Frame.read_var (variable @r{[}, block@r{]})
Return the value of @var{variable} in this frame.  If the optional
argument @var{block} is provided, search for the variable from that
block; otherwise start at the frame's current block (which is
determined by the frame's current program counter).  The @var{variable}
argument must be a string or a @code{gdb.Symbol} object; @var{block} must be a
@code{gdb.Block} object.
@end defun

@defun Frame.select ()
Set this frame to be the selected frame.  @xref{Stack, ,Examining the
Stack}.
@end defun

@defun Frame.level ()
Return an integer, the stack frame level for this frame.  @xref{Frames, ,Stack Frames}.
@end defun

@node Blocks In Python
@subsubsection Accessing blocks from Python

@cindex blocks in python
@tindex gdb.Block

In @value{GDBN}, symbols are stored in blocks.  A block corresponds
roughly to a scope in the source code.  Blocks are organized
hierarchically, and are represented individually in Python as a
@code{gdb.Block}.  Blocks rely on debugging information being
available.

A frame has a block.  Please see @ref{Frames In Python}, for a more
in-depth discussion of frames.

The outermost block is known as the @dfn{global block}.  The global
block typically holds public global variables and functions.

The block nested just inside the global block is the @dfn{static
block}.  The static block typically holds file-scoped variables and
functions.

@value{GDBN} provides a method to get a block's superblock, but there
is currently no way to examine the sub-blocks of a block, or to
iterate over all the blocks in a symbol table (@pxref{Symbol Tables In
Python}).

Here is a short example that should help explain blocks:

@smallexample
/* This is in the global block.  */
int global;

/* This is in the static block.  */
static int file_scope;

/* 'function' is in the global block, and 'argument' is
   in a block nested inside of 'function'.  */
int function (int argument)
@{
  /* 'local' is in a block inside 'function'.  It may or may
     not be in the same block as 'argument'.  */
  int local;

  @{
     /* 'inner' is in a block whose superblock is the one holding
        'local'.  */
     int inner;

     /* If this call is expanded by the compiler, you may see
        a nested block here whose function is 'inline_function'
        and whose superblock is the one holding 'inner'.  */
     inline_function ();
  @}
@}
@end smallexample

A @code{gdb.Block} is iterable.  The iterator returns the symbols
(@pxref{Symbols In Python}) local to the block.  Python programs
should not assume that a specific block object will always contain a
given symbol, since changes in @value{GDBN} features and
infrastructure may cause symbols move across blocks in a symbol
table.  You can also use Python's @dfn{dictionary syntax} to access
variables in this block, e.g.:

@smallexample
symbol = some_block['variable']  # symbol is of type gdb.Symbol
@end smallexample

The following block-related functions are available in the @code{gdb}
module:

@findex gdb.block_for_pc
@defun gdb.block_for_pc (pc)
Return the innermost @code{gdb.Block} containing the given @var{pc}
value.  If the block cannot be found for the @var{pc} value specified,
the function will return @code{None}.  This is identical to
@code{gdb.current_progspace().block_for_pc(pc)} and is included for
historical compatibility.
@end defun

A @code{gdb.Block} object has the following methods:

@defun Block.is_valid ()
Returns @code{True} if the @code{gdb.Block} object is valid,
@code{False} if not.  A block object can become invalid if the block it
refers to doesn't exist anymore in the inferior.  All other
@code{gdb.Block} methods will throw an exception if it is invalid at
the time the method is called.  The block's validity is also checked
during iteration over symbols of the block.
@end defun

A @code{gdb.Block} object has the following attributes:

@defvar Block.start
The start address of the block.  This attribute is not writable.
@end defvar

@defvar Block.end
One past the last address that appears in the block.  This attribute
is not writable.
@end defvar

@defvar Block.function
The name of the block represented as a @code{gdb.Symbol}.  If the
block is not named, then this attribute holds @code{None}.  This
attribute is not writable.

For ordinary function blocks, the superblock is the static block.
However, you should note that it is possible for a function block to
have a superblock that is not the static block -- for instance this
happens for an inlined function.
@end defvar

@defvar Block.superblock
The block containing this block.  If this parent block does not exist,
this attribute holds @code{None}.  This attribute is not writable.
@end defvar

@defvar Block.global_block
The global block associated with this block.  This attribute is not
writable.
@end defvar

@defvar Block.static_block
The static block associated with this block.  This attribute is not
writable.
@end defvar

@defvar Block.is_global
@code{True} if the @code{gdb.Block} object is a global block,
@code{False} if not.  This attribute is not
writable.
@end defvar

@defvar Block.is_static
@code{True} if the @code{gdb.Block} object is a static block,
@code{False} if not.  This attribute is not writable.
@end defvar

@node Symbols In Python
@subsubsection Python representation of Symbols

@cindex symbols in python
@tindex gdb.Symbol

@value{GDBN} represents every variable, function and type as an
entry in a symbol table.  @xref{Symbols, ,Examining the Symbol Table}.
Similarly, Python represents these symbols in @value{GDBN} with the
@code{gdb.Symbol} object.

The following symbol-related functions are available in the @code{gdb}
module:

@findex gdb.lookup_symbol
@defun gdb.lookup_symbol (name @r{[}, block @r{[}, domain@r{]]})
This function searches for a symbol by name.  The search scope can be
restricted to the parameters defined in the optional domain and block
arguments.

@var{name} is the name of the symbol.  It must be a string.  The
optional @var{block} argument restricts the search to symbols visible
in that @var{block}.  The @var{block} argument must be a
@code{gdb.Block} object.  If omitted, the block for the current frame
is used.  The optional @var{domain} argument restricts
the search to the domain type.  The @var{domain} argument must be a
domain constant defined in the @code{gdb} module and described later
in this chapter.

The result is a tuple of two elements.
The first element is a @code{gdb.Symbol} object or @code{None} if the symbol
is not found.
If the symbol is found, the second element is @code{True} if the symbol
is a field of a method's object (e.g., @code{this} in C@t{++}),
otherwise it is @code{False}.
If the symbol is not found, the second element is @code{False}.
@end defun

@findex gdb.lookup_global_symbol
@defun gdb.lookup_global_symbol (name @r{[}, domain@r{]})
This function searches for a global symbol by name.
The search scope can be restricted to by the domain argument.

@var{name} is the name of the symbol.  It must be a string.
The optional @var{domain} argument restricts the search to the domain type.
The @var{domain} argument must be a domain constant defined in the @code{gdb}
module and described later in this chapter.

The result is a @code{gdb.Symbol} object or @code{None} if the symbol
is not found.
@end defun

@findex gdb.lookup_static_symbol
@defun gdb.lookup_static_symbol (name @r{[}, domain@r{]})
This function searches for a global symbol with static linkage by name.
The search scope can be restricted to by the domain argument.

@var{name} is the name of the symbol.  It must be a string.
The optional @var{domain} argument restricts the search to the domain type.
The @var{domain} argument must be a domain constant defined in the @code{gdb}
module and described later in this chapter.

The result is a @code{gdb.Symbol} object or @code{None} if the symbol
is not found.

Note that this function will not find function-scoped static variables. To look
up such variables, iterate over the variables of the function's
@code{gdb.Block} and check that @code{block.addr_class} is
@code{gdb.SYMBOL_LOC_STATIC}.

There can be multiple global symbols with static linkage with the same
name.  This function will only return the first matching symbol that
it finds.  Which symbol is found depends on where @value{GDBN} is
currently stopped, as @value{GDBN} will first search for matching
symbols in the current object file, and then search all other object
files.  If the application is not yet running then @value{GDBN} will
search all object files in the order they appear in the debug
information.
@end defun

@findex gdb.lookup_static_symbols
@defun gdb.lookup_static_symbols (name @r{[}, domain@r{]})
Similar to @code{gdb.lookup_static_symbol}, this function searches for
global symbols with static linkage by name, and optionally restricted
by the domain argument.  However, this function returns a list of all
matching symbols found, not just the first one.

@var{name} is the name of the symbol.  It must be a string.
The optional @var{domain} argument restricts the search to the domain type.
The @var{domain} argument must be a domain constant defined in the @code{gdb}
module and described later in this chapter.

The result is a list of @code{gdb.Symbol} objects which could be empty
if no matching symbols were found.

Note that this function will not find function-scoped static variables. To look
up such variables, iterate over the variables of the function's
@code{gdb.Block} and check that @code{block.addr_class} is
@code{gdb.SYMBOL_LOC_STATIC}.
@end defun

A @code{gdb.Symbol} object has the following attributes:

@defvar Symbol.type
The type of the symbol or @code{None} if no type is recorded.
This attribute is represented as a @code{gdb.Type} object.
@xref{Types In Python}.  This attribute is not writable.
@end defvar

@defvar Symbol.symtab
The symbol table in which the symbol appears.  This attribute is
represented as a @code{gdb.Symtab} object.  @xref{Symbol Tables In
Python}.  This attribute is not writable.
@end defvar

@defvar Symbol.line
The line number in the source code at which the symbol was defined.
This is an integer.
@end defvar

@defvar Symbol.name
The name of the symbol as a string.  This attribute is not writable.
@end defvar

@defvar Symbol.linkage_name
The name of the symbol, as used by the linker (i.e., may be mangled).
This attribute is not writable.
@end defvar

@defvar Symbol.print_name
The name of the symbol in a form suitable for output.  This is either
@code{name} or @code{linkage_name}, depending on whether the user
asked @value{GDBN} to display demangled or mangled names.
@end defvar

@defvar Symbol.addr_class
The address class of the symbol.  This classifies how to find the value
of a symbol.  Each address class is a constant defined in the
@code{gdb} module and described later in this chapter.
@end defvar

@defvar Symbol.needs_frame
This is @code{True} if evaluating this symbol's value requires a frame
(@pxref{Frames In Python}) and @code{False} otherwise.  Typically,
local variables will require a frame, but other symbols will not.
@end defvar

@defvar Symbol.is_argument
@code{True} if the symbol is an argument of a function.
@end defvar

@defvar Symbol.is_constant
@code{True} if the symbol is a constant.
@end defvar

@defvar Symbol.is_function
@code{True} if the symbol is a function or a method.
@end defvar

@defvar Symbol.is_variable
@code{True} if the symbol is a variable.
@end defvar

A @code{gdb.Symbol} object has the following methods:

@defun Symbol.is_valid ()
Returns @code{True} if the @code{gdb.Symbol} object is valid,
@code{False} if not.  A @code{gdb.Symbol} object can become invalid if
the symbol it refers to does not exist in @value{GDBN} any longer.
All other @code{gdb.Symbol} methods will throw an exception if it is
invalid at the time the method is called.
@end defun

@defun Symbol.value (@r{[}frame@r{]})
Compute the value of the symbol, as a @code{gdb.Value}.  For
functions, this computes the address of the function, cast to the
appropriate type.  If the symbol requires a frame in order to compute
its value, then @var{frame} must be given.  If @var{frame} is not
given, or if @var{frame} is invalid, then this method will throw an
exception.
@end defun

The available domain categories in @code{gdb.Symbol} are represented
as constants in the @code{gdb} module:

@vtable @code
@vindex SYMBOL_UNDEF_DOMAIN
@item gdb.SYMBOL_UNDEF_DOMAIN
This is used when a domain has not been discovered or none of the
following domains apply.  This usually indicates an error either
in the symbol information or in @value{GDBN}'s handling of symbols.

@vindex SYMBOL_VAR_DOMAIN
@item gdb.SYMBOL_VAR_DOMAIN
This domain contains variables, function names, typedef names and enum
type values.

@vindex SYMBOL_STRUCT_DOMAIN
@item gdb.SYMBOL_STRUCT_DOMAIN
This domain holds struct, union and enum type names.

@vindex SYMBOL_LABEL_DOMAIN
@item gdb.SYMBOL_LABEL_DOMAIN
This domain contains names of labels (for gotos).

@vindex SYMBOL_MODULE_DOMAIN
@item gdb.SYMBOL_MODULE_DOMAIN
This domain contains names of Fortran module types.

@vindex SYMBOL_COMMON_BLOCK_DOMAIN
@item gdb.SYMBOL_COMMON_BLOCK_DOMAIN
This domain contains names of Fortran common blocks.
@end vtable

The available address class categories in @code{gdb.Symbol} are represented
as constants in the @code{gdb} module:

@vtable @code
@vindex SYMBOL_LOC_UNDEF
@item gdb.SYMBOL_LOC_UNDEF
If this is returned by address class, it indicates an error either in
the symbol information or in @value{GDBN}'s handling of symbols.

@vindex SYMBOL_LOC_CONST
@item gdb.SYMBOL_LOC_CONST
Value is constant int.

@vindex SYMBOL_LOC_STATIC
@item gdb.SYMBOL_LOC_STATIC
Value is at a fixed address.

@vindex SYMBOL_LOC_REGISTER
@item gdb.SYMBOL_LOC_REGISTER
Value is in a register.

@vindex SYMBOL_LOC_ARG
@item gdb.SYMBOL_LOC_ARG
Value is an argument.  This value is at the offset stored within the
symbol inside the frame's argument list.

@vindex SYMBOL_LOC_REF_ARG
@item gdb.SYMBOL_LOC_REF_ARG
Value address is stored in the frame's argument list.  Just like
@code{LOC_ARG} except that the value's address is stored at the
offset, not the value itself.

@vindex SYMBOL_LOC_REGPARM_ADDR
@item gdb.SYMBOL_LOC_REGPARM_ADDR
Value is a specified register.  Just like @code{LOC_REGISTER} except
the register holds the address of the argument instead of the argument
itself.

@vindex SYMBOL_LOC_LOCAL
@item gdb.SYMBOL_LOC_LOCAL
Value is a local variable.

@vindex SYMBOL_LOC_TYPEDEF
@item gdb.SYMBOL_LOC_TYPEDEF
Value not used.  Symbols in the domain @code{SYMBOL_STRUCT_DOMAIN} all
have this class.

@vindex SYMBOL_LOC_LABEL
@item gdb.SYMBOL_LOC_LABEL
Value is a label.

@vindex SYMBOL_LOC_BLOCK
@item gdb.SYMBOL_LOC_BLOCK
Value is a block.

@vindex SYMBOL_LOC_CONST_BYTES
@item gdb.SYMBOL_LOC_CONST_BYTES
Value is a byte-sequence.

@vindex SYMBOL_LOC_UNRESOLVED
@item gdb.SYMBOL_LOC_UNRESOLVED
Value is at a fixed address, but the address of the variable has to be
determined from the minimal symbol table whenever the variable is
referenced.

@vindex SYMBOL_LOC_OPTIMIZED_OUT
@item gdb.SYMBOL_LOC_OPTIMIZED_OUT
The value does not actually exist in the program.

@vindex SYMBOL_LOC_COMPUTED
@item gdb.SYMBOL_LOC_COMPUTED
The value's address is a computed location.

@vindex SYMBOL_LOC_COMMON_BLOCK
@item gdb.SYMBOL_LOC_COMMON_BLOCK
The value's address is a symbol.  This is only used for Fortran common
blocks.
@end vtable

@node Symbol Tables In Python
@subsubsection Symbol table representation in Python

@cindex symbol tables in python
@tindex gdb.Symtab
@tindex gdb.Symtab_and_line

Access to symbol table data maintained by @value{GDBN} on the inferior
is exposed to Python via two objects: @code{gdb.Symtab_and_line} and
@code{gdb.Symtab}.  Symbol table and line data for a frame is returned
from the @code{find_sal} method in @code{gdb.Frame} object.
@xref{Frames In Python}.

For more information on @value{GDBN}'s symbol table management, see
@ref{Symbols, ,Examining the Symbol Table}, for more information.

A @code{gdb.Symtab_and_line} object has the following attributes:

@defvar Symtab_and_line.symtab
The symbol table object (@code{gdb.Symtab}) for this frame.
This attribute is not writable.
@end defvar

@defvar Symtab_and_line.pc
Indicates the start of the address range occupied by code for the
current source line.  This attribute is not writable.
@end defvar

@defvar Symtab_and_line.last
Indicates the end of the address range occupied by code for the current
source line.  This attribute is not writable.
@end defvar

@defvar Symtab_and_line.line
Indicates the current line number for this object.  This
attribute is not writable.
@end defvar

A @code{gdb.Symtab_and_line} object has the following methods:

@defun Symtab_and_line.is_valid ()
Returns @code{True} if the @code{gdb.Symtab_and_line} object is valid,
@code{False} if not.  A @code{gdb.Symtab_and_line} object can become
invalid if the Symbol table and line object it refers to does not
exist in @value{GDBN} any longer.  All other
@code{gdb.Symtab_and_line} methods will throw an exception if it is
invalid at the time the method is called.
@end defun

A @code{gdb.Symtab} object has the following attributes:

@defvar Symtab.filename
The symbol table's source filename.  This attribute is not writable.
@end defvar

@defvar Symtab.objfile
The symbol table's backing object file.  @xref{Objfiles In Python}.
This attribute is not writable.
@end defvar

@defvar Symtab.producer
The name and possibly version number of the program that
compiled the code in the symbol table.
The contents of this string is up to the compiler.
If no producer information is available then @code{None} is returned.
This attribute is not writable.
@end defvar

A @code{gdb.Symtab} object has the following methods:

@defun Symtab.is_valid ()
Returns @code{True} if the @code{gdb.Symtab} object is valid,
@code{False} if not.  A @code{gdb.Symtab} object can become invalid if
the symbol table it refers to does not exist in @value{GDBN} any
longer.  All other @code{gdb.Symtab} methods will throw an exception
if it is invalid at the time the method is called.
@end defun

@defun Symtab.fullname ()
Return the symbol table's source absolute file name.
@end defun

@defun Symtab.global_block ()
Return the global block of the underlying symbol table.
@xref{Blocks In Python}.
@end defun

@defun Symtab.static_block ()
Return the static block of the underlying symbol table.
@xref{Blocks In Python}.
@end defun

@defun Symtab.linetable ()
Return the line table associated with the symbol table.
@xref{Line Tables In Python}.
@end defun

@node Line Tables In Python
@subsubsection Manipulating line tables using Python

@cindex line tables in python
@tindex gdb.LineTable

Python code can request and inspect line table information from a
symbol table that is loaded in @value{GDBN}.  A line table is a
mapping of source lines to their executable locations in memory.  To
acquire the line table information for a particular symbol table, use
the @code{linetable} function (@pxref{Symbol Tables In Python}).

A @code{gdb.LineTable} is iterable.  The iterator returns
@code{LineTableEntry} objects that correspond to the source line and
address for each line table entry.  @code{LineTableEntry} objects have
the following attributes:

@defvar LineTableEntry.line
The source line number for this line table entry.  This number
corresponds to the actual line of source.  This attribute is not
writable.
@end defvar

@defvar LineTableEntry.pc
The address that is associated with the line table entry where the
executable code for that source line resides in memory.  This
attribute is not writable.
@end defvar

As there can be multiple addresses for a single source line, you may
receive multiple @code{LineTableEntry} objects with matching
@code{line} attributes, but with different @code{pc} attributes.  The
iterator is sorted in ascending @code{pc} order.  Here is a small
example illustrating iterating over a line table.

@smallexample
symtab = gdb.selected_frame().find_sal().symtab
linetable = symtab.linetable()
for line in linetable:
   print ("Line: "+str(line.line)+" Address: "+hex(line.pc))
@end smallexample

This will have the following output:

@smallexample
Line: 33 Address: 0x4005c8L
Line: 37 Address: 0x4005caL
Line: 39 Address: 0x4005d2L
Line: 40 Address: 0x4005f8L
Line: 42 Address: 0x4005ffL
Line: 44 Address: 0x400608L
Line: 42 Address: 0x40060cL
Line: 45 Address: 0x400615L
@end smallexample

In addition to being able to iterate over a @code{LineTable}, it also
has the following direct access methods:

@defun LineTable.line (line)
Return a Python @code{Tuple} of @code{LineTableEntry} objects for any
entries in the line table for the given @var{line}, which specifies
the source code line.  If there are no entries for that source code
@var{line}, the Python @code{None} is returned.
@end defun

@defun LineTable.has_line (line)
Return a Python @code{Boolean} indicating whether there is an entry in
the line table for this source line.  Return @code{True} if an entry
is found, or @code{False} if not.
@end defun

@defun LineTable.source_lines ()
Return a Python @code{List} of the source line numbers in the symbol
table.  Only lines with executable code locations are returned.  The
contents of the @code{List} will just be the source line entries
represented as Python @code{Long} values.
@end defun

@node Breakpoints In Python
@subsubsection Manipulating breakpoints using Python

@cindex breakpoints in python
@tindex gdb.Breakpoint

Python code can manipulate breakpoints via the @code{gdb.Breakpoint}
class.

A breakpoint can be created using one of the two forms of the
@code{gdb.Breakpoint} constructor.  The first one accepts a string
like one would pass to the @code{break}
(@pxref{Set Breaks,,Setting Breakpoints}) and @code{watch}
(@pxref{Set Watchpoints, , Setting Watchpoints}) commands, and can be used to
create both breakpoints and watchpoints.  The second accepts separate Python
arguments similar to @ref{Explicit Locations}, and can only be used to create
breakpoints.

@defun Breakpoint.__init__ (spec @r{[}, type @r{][}, wp_class @r{][}, internal @r{][}, temporary @r{][}, qualified @r{]})
Create a new breakpoint according to @var{spec}, which is a string naming the
location of a breakpoint, or an expression that defines a watchpoint.  The
string should describe a location in a format recognized by the @code{break}
command (@pxref{Set Breaks,,Setting Breakpoints}) or, in the case of a
watchpoint, by the @code{watch} command
(@pxref{Set Watchpoints, , Setting Watchpoints}).

The optional @var{type} argument specifies the type of the breakpoint to create,
as defined below.

The optional @var{wp_class} argument defines the class of watchpoint to create,
if @var{type} is @code{gdb.BP_WATCHPOINT}.  If @var{wp_class} is omitted, it
defaults to @code{gdb.WP_WRITE}.

The optional @var{internal} argument allows the breakpoint to become invisible
to the user.  The breakpoint will neither be reported when created, nor will it
be listed in the output from @code{info breakpoints} (but will be listed with
the @code{maint info breakpoints} command).

The optional @var{temporary} argument makes the breakpoint a temporary
breakpoint.  Temporary breakpoints are deleted after they have been hit.  Any
further access to the Python breakpoint after it has been hit will result in a
runtime error (as that breakpoint has now been automatically deleted).

The optional @var{qualified} argument is a boolean that allows interpreting
the function passed in @code{spec} as a fully-qualified name.  It is equivalent
to @code{break}'s @code{-qualified} flag (@pxref{Linespec Locations} and
@ref{Explicit Locations}).

@end defun

@defun Breakpoint.__init__ (@r{[} source @r{][}, function @r{][}, label @r{][}, line @r{]}, @r{][} internal @r{][}, temporary @r{][}, qualified @r{]})
This second form of creating a new breakpoint specifies the explicit
location (@pxref{Explicit Locations}) using keywords.  The new breakpoint will
be created in the specified source file @var{source}, at the specified
@var{function}, @var{label} and @var{line}.

@var{internal}, @var{temporary} and @var{qualified} have the same usage as
explained previously.
@end defun

The available types are represented by constants defined in the @code{gdb}
module:

@vtable @code
@vindex BP_BREAKPOINT
@item gdb.BP_BREAKPOINT
Normal code breakpoint.

@vindex BP_HARDWARE_BREAKPOINT
@item gdb.BP_HARDWARE_BREAKPOINT
Hardware assisted code breakpoint.

@vindex BP_WATCHPOINT
@item gdb.BP_WATCHPOINT
Watchpoint breakpoint.

@vindex BP_HARDWARE_WATCHPOINT
@item gdb.BP_HARDWARE_WATCHPOINT
Hardware assisted watchpoint.

@vindex BP_READ_WATCHPOINT
@item gdb.BP_READ_WATCHPOINT
Hardware assisted read watchpoint.

@vindex BP_ACCESS_WATCHPOINT
@item gdb.BP_ACCESS_WATCHPOINT
Hardware assisted access watchpoint.

@vindex BP_CATCHPOINT
@item gdb.BP_CATCHPOINT
Catchpoint.  Currently, this type can't be used when creating
@code{gdb.Breakpoint} objects, but will be present in
@code{gdb.Breakpoint} objects reported from
@code{gdb.BreakpointEvent}s (@pxref{Events In Python}).
@end vtable

The available watchpoint types are represented by constants defined in the
@code{gdb} module:

@vtable @code
@vindex WP_READ
@item gdb.WP_READ
Read only watchpoint.

@vindex WP_WRITE
@item gdb.WP_WRITE
Write only watchpoint.

@vindex WP_ACCESS
@item gdb.WP_ACCESS
Read/Write watchpoint.
@end vtable

@defun Breakpoint.stop (self)
The @code{gdb.Breakpoint} class can be sub-classed and, in
particular, you may choose to implement the @code{stop} method.
If this method is defined in a sub-class of @code{gdb.Breakpoint},
it will be called when the inferior reaches any location of a
breakpoint which instantiates that sub-class.  If the method returns
@code{True}, the inferior will be stopped at the location of the
breakpoint, otherwise the inferior will continue.

If there are multiple breakpoints at the same location with a
@code{stop} method, each one will be called regardless of the
return status of the previous.  This ensures that all @code{stop}
methods have a chance to execute at that location.  In this scenario
if one of the methods returns @code{True} but the others return
@code{False}, the inferior will still be stopped.

You should not alter the execution state of the inferior (i.e.@:, step,
next, etc.), alter the current frame context (i.e.@:, change the current
active frame), or alter, add or delete any breakpoint.  As a general
rule, you should not alter any data within @value{GDBN} or the inferior
at this time.

Example @code{stop} implementation:

@smallexample
class MyBreakpoint (gdb.Breakpoint):
      def stop (self):
        inf_val = gdb.parse_and_eval("foo")
        if inf_val == 3:
          return True
        return False
@end smallexample
@end defun

@defun Breakpoint.is_valid ()
Return @code{True} if this @code{Breakpoint} object is valid,
@code{False} otherwise.  A @code{Breakpoint} object can become invalid
if the user deletes the breakpoint.  In this case, the object still
exists, but the underlying breakpoint does not.  In the cases of
watchpoint scope, the watchpoint remains valid even if execution of the
inferior leaves the scope of that watchpoint.
@end defun

@defun Breakpoint.delete ()
Permanently deletes the @value{GDBN} breakpoint.  This also
invalidates the Python @code{Breakpoint} object.  Any further access
to this object's attributes or methods will raise an error.
@end defun

@defvar Breakpoint.enabled
This attribute is @code{True} if the breakpoint is enabled, and
@code{False} otherwise.  This attribute is writable.  You can use it to enable
or disable the breakpoint.
@end defvar

@defvar Breakpoint.silent
This attribute is @code{True} if the breakpoint is silent, and
@code{False} otherwise.  This attribute is writable.

Note that a breakpoint can also be silent if it has commands and the
first command is @code{silent}.  This is not reported by the
@code{silent} attribute.
@end defvar

@defvar Breakpoint.pending
This attribute is @code{True} if the breakpoint is pending, and
@code{False} otherwise.  @xref{Set Breaks}.  This attribute is
read-only.
@end defvar

@anchor{python_breakpoint_thread}
@defvar Breakpoint.thread
If the breakpoint is thread-specific, this attribute holds the
thread's global id.  If the breakpoint is not thread-specific, this
attribute is @code{None}.  This attribute is writable.
@end defvar

@defvar Breakpoint.task
If the breakpoint is Ada task-specific, this attribute holds the Ada task
id.  If the breakpoint is not task-specific (or the underlying
language is not Ada), this attribute is @code{None}.  This attribute
is writable.
@end defvar

@defvar Breakpoint.ignore_count
This attribute holds the ignore count for the breakpoint, an integer.
This attribute is writable.
@end defvar

@defvar Breakpoint.number
This attribute holds the breakpoint's number --- the identifier used by
the user to manipulate the breakpoint.  This attribute is not writable.
@end defvar

@defvar Breakpoint.type
This attribute holds the breakpoint's type --- the identifier used to
determine the actual breakpoint type or use-case.  This attribute is not
writable.
@end defvar

@defvar Breakpoint.visible
This attribute tells whether the breakpoint is visible to the user
when set, or when the @samp{info breakpoints} command is run.  This
attribute is not writable.
@end defvar

@defvar Breakpoint.temporary
This attribute indicates whether the breakpoint was created as a
temporary breakpoint.  Temporary breakpoints are automatically deleted
after that breakpoint has been hit.  Access to this attribute, and all
other attributes and functions other than the @code{is_valid}
function, will result in an error after the breakpoint has been hit
(as it has been automatically deleted).  This attribute is not
writable.
@end defvar

@defvar Breakpoint.hit_count
This attribute holds the hit count for the breakpoint, an integer.
This attribute is writable, but currently it can only be set to zero.
@end defvar

@defvar Breakpoint.location
This attribute holds the location of the breakpoint, as specified by
the user.  It is a string.  If the breakpoint does not have a location
(that is, it is a watchpoint) the attribute's value is @code{None}.  This
attribute is not writable.
@end defvar

@defvar Breakpoint.expression
This attribute holds a breakpoint expression, as specified by
the user.  It is a string.  If the breakpoint does not have an
expression (the breakpoint is not a watchpoint) the attribute's value
is @code{None}.  This attribute is not writable.
@end defvar

@defvar Breakpoint.condition
This attribute holds the condition of the breakpoint, as specified by
the user.  It is a string.  If there is no condition, this attribute's
value is @code{None}.  This attribute is writable.
@end defvar

@defvar Breakpoint.commands
This attribute holds the commands attached to the breakpoint.  If
there are commands, this attribute's value is a string holding all the
commands, separated by newlines.  If there are no commands, this
attribute is @code{None}.  This attribute is writable.
@end defvar

@node Finish Breakpoints in Python
@subsubsection Finish Breakpoints

@cindex python finish breakpoints
@tindex gdb.FinishBreakpoint

A finish breakpoint is a temporary breakpoint set at the return address of
a frame, based on the @code{finish} command.  @code{gdb.FinishBreakpoint}
extends @code{gdb.Breakpoint}.  The underlying breakpoint will be disabled 
and deleted when the execution will run out of the breakpoint scope (i.e.@: 
@code{Breakpoint.stop} or @code{FinishBreakpoint.out_of_scope} triggered).
Finish breakpoints are thread specific and must be create with the right 
thread selected.  
 
@defun FinishBreakpoint.__init__ (@r{[}frame@r{]} @r{[}, internal@r{]})
Create a finish breakpoint at the return address of the @code{gdb.Frame}
object @var{frame}.  If @var{frame} is not provided, this defaults to the
newest frame.  The optional @var{internal} argument allows the breakpoint to
become invisible to the user.  @xref{Breakpoints In Python}, for further 
details about this argument.
@end defun

@defun FinishBreakpoint.out_of_scope (self)
In some circumstances (e.g.@: @code{longjmp}, C@t{++} exceptions, @value{GDBN} 
@code{return} command, @dots{}), a function may not properly terminate, and
thus never hit the finish breakpoint.  When @value{GDBN} notices such a
situation, the @code{out_of_scope} callback will be triggered.

You may want to sub-class @code{gdb.FinishBreakpoint} and override this
method:

@smallexample
class MyFinishBreakpoint (gdb.FinishBreakpoint)
    def stop (self):
        print ("normal finish")
        return True
    
    def out_of_scope ():
        print ("abnormal finish")
@end smallexample 
@end defun

@defvar FinishBreakpoint.return_value
When @value{GDBN} is stopped at a finish breakpoint and the frame 
used to build the @code{gdb.FinishBreakpoint} object had debug symbols, this
attribute will contain a @code{gdb.Value} object corresponding to the return
value of the function.  The value will be @code{None} if the function return 
type is @code{void} or if the return value was not computable.  This attribute
is not writable.
@end defvar

@node Lazy Strings In Python
@subsubsection Python representation of lazy strings

@cindex lazy strings in python
@tindex gdb.LazyString

A @dfn{lazy string} is a string whose contents is not retrieved or
encoded until it is needed.

A @code{gdb.LazyString} is represented in @value{GDBN} as an
@code{address} that points to a region of memory, an @code{encoding}
that will be used to encode that region of memory, and a @code{length}
to delimit the region of memory that represents the string.  The
difference between a @code{gdb.LazyString} and a string wrapped within
a @code{gdb.Value} is that a @code{gdb.LazyString} will be treated
differently by @value{GDBN} when printing.  A @code{gdb.LazyString} is
retrieved and encoded during printing, while a @code{gdb.Value}
wrapping a string is immediately retrieved and encoded on creation.

A @code{gdb.LazyString} object has the following functions:

@defun LazyString.value ()
Convert the @code{gdb.LazyString} to a @code{gdb.Value}.  This value
will point to the string in memory, but will lose all the delayed
retrieval, encoding and handling that @value{GDBN} applies to a
@code{gdb.LazyString}.
@end defun

@defvar LazyString.address
This attribute holds the address of the string.  This attribute is not
writable.
@end defvar

@defvar LazyString.length
This attribute holds the length of the string in characters.  If the
length is -1, then the string will be fetched and encoded up to the
first null of appropriate width.  This attribute is not writable.
@end defvar

@defvar LazyString.encoding
This attribute holds the encoding that will be applied to the string
when the string is printed by @value{GDBN}.  If the encoding is not
set, or contains an empty string,  then @value{GDBN} will select the
most appropriate encoding when the string is printed.  This attribute
is not writable.
@end defvar

@defvar LazyString.type
This attribute holds the type that is represented by the lazy string's
type.  For a lazy string this is a pointer or array type.  To
resolve this to the lazy string's character type, use the type's
@code{target} method.  @xref{Types In Python}.  This attribute is not
writable.
@end defvar

@node Architectures In Python
@subsubsection Python representation of architectures
@cindex Python architectures

@value{GDBN} uses architecture specific parameters and artifacts in a
number of its various computations.  An architecture is represented
by an instance of the @code{gdb.Architecture} class.

A @code{gdb.Architecture} class has the following methods:

@defun Architecture.name ()
Return the name (string value) of the architecture.
@end defun

@defun Architecture.disassemble (@var{start_pc} @r{[}, @var{end_pc} @r{[}, @var{count}@r{]]})
Return a list of disassembled instructions starting from the memory
address @var{start_pc}.  The optional arguments @var{end_pc} and
@var{count} determine the number of instructions in the returned list.
If both the optional arguments @var{end_pc} and @var{count} are
specified, then a list of at most @var{count} disassembled instructions
whose start address falls in the closed memory address interval from
@var{start_pc} to @var{end_pc} are returned.  If @var{end_pc} is not
specified, but @var{count} is specified, then @var{count} number of
instructions starting from the address @var{start_pc} are returned.  If
@var{count} is not specified but @var{end_pc} is specified, then all
instructions whose start address falls in the closed memory address
interval from @var{start_pc} to @var{end_pc} are returned.  If neither
@var{end_pc} nor @var{count} are specified, then a single instruction at
@var{start_pc} is returned.  For all of these cases, each element of the
returned list is a Python @code{dict} with the following string keys:

@table @code

@item addr
The value corresponding to this key is a Python long integer capturing
the memory address of the instruction.

@item asm
The value corresponding to this key is a string value which represents
the instruction with assembly language mnemonics.  The assembly
language flavor used is the same as that specified by the current CLI
variable @code{disassembly-flavor}.  @xref{Machine Code}.

@item length
The value corresponding to this key is the length (integer value) of the
instruction in bytes.

@end table
@end defun

@anchor{gdbpy_architecture_registers}
@defun Architecture.registers (@r{[} @var{reggroup} @r{]})
Return a @code{gdb.RegisterDescriptorIterator} (@pxref{Registers In
Python}) for all of the registers in @var{reggroup}, a string that is
the name of a register group.  If @var{reggroup} is omitted, or is the
empty string, then the register group @samp{all} is assumed.
@end defun

@anchor{gdbpy_architecture_reggroups}
@defun Architecture.register_groups ()
Return a @code{gdb.RegisterGroupsIterator} (@pxref{Registers In
Python}) for all of the register groups available for the
@code{gdb.Architecture}.
@end defun

@node Registers In Python
@subsubsection Registers In Python
@cindex Registers In Python

Python code can request from a @code{gdb.Architecture} information
about the set of registers available
(@pxref{gdbpy_architecture_registers,,@code{Architecture.registers}}).
The register information is returned as a
@code{gdb.RegisterDescriptorIterator}, which is an iterator that in
turn returns @code{gdb.RegisterDescriptor} objects.

A @code{gdb.RegisterDescriptor} does not provide the value of a
register (@pxref{gdbpy_frame_read_register,,@code{Frame.read_register}}
for reading a register's value), instead the @code{RegisterDescriptor}
is a way to discover which registers are available for a particular
architecture.

A @code{gdb.RegisterDescriptor} has the following read-only properties:

@defvar RegisterDescriptor.name
The name of this register.
@end defvar

It is also possible to lookup a register descriptor based on its name
using the following @code{gdb.RegisterDescriptorIterator} function:

@defun RegisterDescriptorIterator.find (@var{name})
Takes @var{name} as an argument, which must be a string, and returns a
@code{gdb.RegisterDescriptor} for the register with that name, or
@code{None} if there is no register with that name.
@end defun

Python code can also request from a @code{gdb.Architecture}
information about the set of register groups available on a given
architecture
(@pxref{gdbpy_architecture_reggroups,,@code{Architecture.register_groups}}).

Every register can be a member of zero or more register groups.  Some
register groups are used internally within @value{GDBN} to control
things like which registers must be saved when calling into the
program being debugged (@pxref{Calling,,Calling Program Functions}).
Other register groups exist to allow users to easily see related sets
of registers in commands like @code{info registers}
(@pxref{info_registers_reggroup,,@code{info registers
@var{reggroup}}}).

The register groups information is returned as a
@code{gdb.RegisterGroupsIterator}, which is an iterator that in turn
returns @code{gdb.RegisterGroup} objects.

A @code{gdb.RegisterGroup} object has the following read-only
properties:

@defvar RegisterGroup.name
A string that is the name of this register group.
@end defvar

@node TUI Windows In Python
@subsubsection Implementing new TUI windows
@cindex Python TUI Windows

New TUI (@pxref{TUI}) windows can be implemented in Python.

@findex gdb.register_window_type
@defun gdb.register_window_type (@var{name}, @var{factory})
Because TUI windows are created and destroyed depending on the layout
the user chooses, new window types are implemented by registering a
factory function with @value{GDBN}.

@var{name} is the name of the new window.  It's an error to try to
replace one of the built-in windows, but other window types can be
replaced.

@var{function} is a factory function that is called to create the TUI
window.  This is called with a single argument of type
@code{gdb.TuiWindow}, described below.  It should return an object
that implements the TUI window protocol, also described below.
@end defun

As mentioned above, when a factory function is called, it is passed
an object of type @code{gdb.TuiWindow}.  This object has these
methods and attributes:

@defun TuiWindow.is_valid ()
This method returns @code{True} when this window is valid.  When the
user changes the TUI layout, windows no longer visible in the new
layout will be destroyed.  At this point, the @code{gdb.TuiWindow}
will no longer be valid, and methods (and attributes) other than
@code{is_valid} will throw an exception.

When the TUI is disabled using @code{tui disable} (@pxref{TUI
Commands,,tui disable}) the window is hidden rather than destroyed,
but @code{is_valid} will still return @code{False} and other methods
(and attributes) will still throw an exception.
@end defun

@defvar TuiWindow.width
This attribute holds the width of the window.  It is not writable.
@end defvar

@defvar TuiWindow.height
This attribute holds the height of the window.  It is not writable.
@end defvar

@defvar TuiWindow.title
This attribute holds the window's title, a string.  This is normally
displayed above the window.  This attribute can be modified.
@end defvar

@defun TuiWindow.erase ()
Remove all the contents of the window.
@end defun

@defun TuiWindow.write (@var{string} @r{[}, @var{full_window}@r{]})
Write @var{string} to the window.  @var{string} can contain ANSI
terminal escape styling sequences; @value{GDBN} will translate these
as appropriate for the terminal.

If the @var{full_window} parameter is @code{True}, then @var{string}
contains the full contents of the window.  This is similar to calling
@code{erase} before @code{write}, but avoids the flickering.
@end defun

The factory function that you supply should return an object
conforming to the TUI window protocol.  These are the method that can
be called on this object, which is referred to below as the ``window
object''.  The methods documented below are optional; if the object
does not implement one of these methods, @value{GDBN} will not attempt
to call it.  Additional new methods may be added to the window
protocol in the future.  @value{GDBN} guarantees that they will begin
with a lower-case letter, so you can start implementation methods with
upper-case letters or underscore to avoid any future conflicts.

@defun Window.close ()
When the TUI window is closed, the @code{gdb.TuiWindow} object will be
put into an invalid state.  At this time, @value{GDBN} will call
@code{close} method on the window object.

After this method is called, @value{GDBN} will discard any references
it holds on this window object, and will no longer call methods on
this object.
@end defun

@defun Window.render ()
In some situations, a TUI window can change size.  For example, this
can happen if the user resizes the terminal, or changes the layout.
When this happens, @value{GDBN} will call the @code{render} method on
the window object.

If your window is intended to update in response to changes in the
inferior, you will probably also want to register event listeners and
send output to the @code{gdb.TuiWindow}.
@end defun

@defun Window.hscroll (@var{num})
This is a request to scroll the window horizontally.  @var{num} is the
amount by which to scroll, with negative numbers meaning to scroll
right.  In the TUI model, it is the viewport that moves, not the
contents.  A positive argument should cause the viewport to move
right, and so the content should appear to move to the left.
@end defun

@defun Window.vscroll (@var{num})
This is a request to scroll the window vertically.  @var{num} is the
amount by which to scroll, with negative numbers meaning to scroll
backward.  In the TUI model, it is the viewport that moves, not the
contents.  A positive argument should cause the viewport to move down,
and so the content should appear to move up.
@end defun

@defun Window.click (@var{x}, @var{y}, @var{button})
This is called on a mouse click in this window.  @var{x} and @var{y} are
the mouse coordinates inside the window (0-based), and @var{button}
specifies which mouse button was used, whose values can be 1 (left),
2 (middle), or 3 (right).
@end defun

@node Python Auto-loading
@subsection Python Auto-loading
@cindex Python auto-loading

When a new object file is read (for example, due to the @code{file}
command, or because the inferior has loaded a shared library),
@value{GDBN} will look for Python support scripts in several ways:
@file{@var{objfile}-gdb.py} and @code{.debug_gdb_scripts} section.
@xref{Auto-loading extensions}.

The auto-loading feature is useful for supplying application-specific
debugging commands and scripts.

Auto-loading can be enabled or disabled,
and the list of auto-loaded scripts can be printed.

@table @code
@anchor{set auto-load python-scripts}
@kindex set auto-load python-scripts
@item set auto-load python-scripts [on|off]
Enable or disable the auto-loading of Python scripts.

@anchor{show auto-load python-scripts}
@kindex show auto-load python-scripts
@item show auto-load python-scripts
Show whether auto-loading of Python scripts is enabled or disabled.

@anchor{info auto-load python-scripts}
@kindex info auto-load python-scripts
@cindex print list of auto-loaded Python scripts
@item info auto-load python-scripts [@var{regexp}]
Print the list of all Python scripts that @value{GDBN} auto-loaded.

Also printed is the list of Python scripts that were mentioned in
the @code{.debug_gdb_scripts} section and were either not found
(@pxref{dotdebug_gdb_scripts section}) or were not auto-loaded due to
@code{auto-load safe-path} rejection (@pxref{Auto-loading}).
This is useful because their names are not printed when @value{GDBN}
tries to load them and fails.  There may be many of them, and printing
an error message for each one is problematic.

If @var{regexp} is supplied only Python scripts with matching names are printed.

Example:

@smallexample
(gdb) info auto-load python-scripts
Loaded Script
Yes    py-section-script.py
       full name: /tmp/py-section-script.py
No     my-foo-pretty-printers.py
@end smallexample
@end table

When reading an auto-loaded file or script, @value{GDBN} sets the
@dfn{current objfile}.  This is available via the @code{gdb.current_objfile}
function (@pxref{Objfiles In Python}).  This can be useful for
registering objfile-specific pretty-printers and frame-filters.

@node Python modules
@subsection Python modules
@cindex python modules

@value{GDBN} comes with several modules to assist writing Python code.

@menu
* gdb.printing::       Building and registering pretty-printers.
* gdb.types::          Utilities for working with types.
* gdb.prompt::         Utilities for prompt value substitution.
@end menu

@node gdb.printing
@subsubsection gdb.printing
@cindex gdb.printing

This module provides a collection of utilities for working with
pretty-printers.

@table @code
@item PrettyPrinter (@var{name}, @var{subprinters}=None)
This class specifies the API that makes @samp{info pretty-printer},
@samp{enable pretty-printer} and @samp{disable pretty-printer} work.
Pretty-printers should generally inherit from this class.

@item SubPrettyPrinter (@var{name})
For printers that handle multiple types, this class specifies the
corresponding API for the subprinters.

@item RegexpCollectionPrettyPrinter (@var{name})
Utility class for handling multiple printers, all recognized via
regular expressions.
@xref{Writing a Pretty-Printer}, for an example.

@item FlagEnumerationPrinter (@var{name})
A pretty-printer which handles printing of @code{enum} values.  Unlike
@value{GDBN}'s built-in @code{enum} printing, this printer attempts to
work properly when there is some overlap between the enumeration
constants.  The argument @var{name} is the name of the printer and
also the name of the @code{enum} type to look up.

@item register_pretty_printer (@var{obj}, @var{printer}, @var{replace}=False)
Register @var{printer} with the pretty-printer list of @var{obj}.
If @var{replace} is @code{True} then any existing copy of the printer
is replaced.  Otherwise a @code{RuntimeError} exception is raised
if a printer with the same name already exists.
@end table

@node gdb.types
@subsubsection gdb.types
@cindex gdb.types

This module provides a collection of utilities for working with
@code{gdb.Type} objects.

@table @code
@item get_basic_type (@var{type})
Return @var{type} with const and volatile qualifiers stripped,
and with typedefs and C@t{++} references converted to the underlying type.

C@t{++} example:

@smallexample
typedef const int const_int;
const_int foo (3);
const_int& foo_ref (foo);
int main () @{ return 0; @}
@end smallexample

Then in gdb:

@smallexample
(gdb) start
(gdb) python import gdb.types
(gdb) python foo_ref = gdb.parse_and_eval("foo_ref")
(gdb) python print gdb.types.get_basic_type(foo_ref.type)
int
@end smallexample

@item has_field (@var{type}, @var{field})
Return @code{True} if @var{type}, assumed to be a type with fields
(e.g., a structure or union), has field @var{field}.

@item make_enum_dict (@var{enum_type})
Return a Python @code{dictionary} type produced from @var{enum_type}.

@item deep_items (@var{type})
Returns a Python iterator similar to the standard
@code{gdb.Type.iteritems} method, except that the iterator returned
by @code{deep_items} will recursively traverse anonymous struct or
union fields.  For example:

@smallexample
struct A
@{
    int a;
    union @{
        int b0;
        int b1;
    @};
@};
@end smallexample

@noindent
Then in @value{GDBN}:
@smallexample
(@value{GDBP}) python import gdb.types
(@value{GDBP}) python struct_a = gdb.lookup_type("struct A")
(@value{GDBP}) python print struct_a.keys ()
@{['a', '']@}
(@value{GDBP}) python print [k for k,v in gdb.types.deep_items(struct_a)]
@{['a', 'b0', 'b1']@}
@end smallexample

@item get_type_recognizers ()
Return a list of the enabled type recognizers for the current context.
This is called by @value{GDBN} during the type-printing process
(@pxref{Type Printing API}).

@item apply_type_recognizers (recognizers, type_obj)
Apply the type recognizers, @var{recognizers}, to the type object
@var{type_obj}.  If any recognizer returns a string, return that
string.  Otherwise, return @code{None}.  This is called by
@value{GDBN} during the type-printing process (@pxref{Type Printing
API}).

@item register_type_printer (locus, printer)
This is a convenience function to register a type printer
@var{printer}.  The printer must implement the type printer protocol.
The @var{locus} argument is either a @code{gdb.Objfile}, in which case
the printer is registered with that objfile; a @code{gdb.Progspace},
in which case the printer is registered with that progspace; or
@code{None}, in which case the printer is registered globally.

@item TypePrinter
This is a base class that implements the type printer protocol.  Type
printers are encouraged, but not required, to derive from this class.
It defines a constructor:

@defmethod TypePrinter __init__ (self, name)
Initialize the type printer with the given name.  The new printer
starts in the enabled state.
@end defmethod

@end table

@node gdb.prompt
@subsubsection gdb.prompt
@cindex gdb.prompt

This module provides a method for prompt value-substitution.

@table @code
@item substitute_prompt (@var{string})
Return @var{string} with escape sequences substituted by values.  Some
escape sequences take arguments.  You can specify arguments inside
``@{@}'' immediately following the escape sequence.

The escape sequences you can pass to this function are:

@table @code
@item \\
Substitute a backslash.
@item \e
Substitute an ESC character.
@item \f
Substitute the selected frame; an argument names a frame parameter.
@item \n
Substitute a newline.
@item \p
Substitute a parameter's value; the argument names the parameter.
@item \r
Substitute a carriage return.
@item \t
Substitute the selected thread; an argument names a thread parameter.
@item \v
Substitute the version of GDB.
@item \w
Substitute the current working directory.
@item \[
Begin a sequence of non-printing characters.  These sequences are
typically used with the ESC character, and are not counted in the string
length.  Example: ``\[\e[0;34m\](gdb)\[\e[0m\]'' will return a
blue-colored ``(gdb)'' prompt where the length is five.
@item \]
End a sequence of non-printing characters.
@end table

For example:

@smallexample
substitute_prompt ("frame: \f, args: \p@{print frame-arguments@}")
@end smallexample

@exdent will return the string:

@smallexample
"frame: main, args: scalars"
@end smallexample
@end table
