@c Copyright (C) 2008--2023 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}.

@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

@anchor{set_python_print_stack}
@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, provided
the @code{python ignore-environment} setting is @samp{off}, the
environment variable @env{PYTHONDONTWRITEBYTECODE} is examined to see
if it should write out byte-code or not.
@env{PYTHONDONTWRITEBYTECODE} is considered to be off/disabled either
when set to the empty string or when the environment variable doesn't
exist.  All other settings, including those which don't seem to make
sense, indicate that it's on/enabled.

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.
* Threading in GDB::		Using Python threads in GDB.
* 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.
* CLI Commands In Python::      Implementing new CLI commands in Python.
* GDB/MI Commands In Python::   Implementing new @sc{gdb/mi} 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.
* Connections In Python::       Python representation of connections.
* TUI Windows In Python::       Implementing new TUI windows.
* Disassembly In Python::       Instruction Disassembly In Python
@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.

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

@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

@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

@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

@defun gdb.set_parameter (name, value)
Sets the gdb parameter @var{name} to @var{value}.  As with
@code{gdb.parameter}, the parameter name string may contain spaces if
the parameter has a multi-part name.
@end defun

@defun gdb.with_parameter (name, value)
Create a Python context manager (for use with the Python
@command{with} statement) that temporarily sets the gdb parameter
@var{name} to @var{value}.  On exit from the context, the previous
value will be restored.

This uses @code{gdb.parameter} in its implementation, so it can throw
the same exceptions as that function.

For example, it's sometimes useful to evaluate some Python code with a
particular gdb language:

@smallexample
with gdb.with_parameter('language', 'pascal'):
  ... language-specific operations
@end smallexample
@end defun

@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

@defun gdb.add_history (value)
Takes @var{value}, an instance of @code{gdb.Value} (@pxref{Values From
Inferior}), and appends the value this object represents to
@value{GDBN}'s value history (@pxref{Value History}), and return an
integer, its history number.  If @var{value} is not a
@code{gdb.Value}, it is is converted using the @code{gdb.Value}
constructor.  If @var{value} can't be converted to a @code{gdb.Value}
then a @code{TypeError} is raised.

When a command implemented in Python prints a single @code{gdb.Value}
as its result, then placing the value into the history will allow the
user convenient access to those values via CLI history facilities.
@end defun

@defun gdb.history_count ()
Return an integer indicating the number of values in @value{GDBN}'s
value history (@pxref{Value History}).
@end defun

@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

@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

@defun gdb.parse_and_eval (expression @r{[}, global_context@r{]})
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}.

@var{global_context}, if provided, is a boolean indicating whether the
parsing should be done in the global context.  The default is
@samp{False}, meaning that the current frame or current static context
should be used.

This function can be useful when implementing a new command
(@pxref{CLI Commands In Python}, @pxref{GDB/MI 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

@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

@defun gdb.write (string @r{[}, stream@r{]})
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

@defun gdb.flush (@r{[}, stream@r{]})
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

@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

@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

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

@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

@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{Location
Specifications}).
@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

@anchor{gdb_architecture_names}
@defun gdb.architecture_names ()
Return a list containing all of the architecture names that the
current build of @value{GDBN} supports.  Each architecture name is a
string.  The names returned in this list are the same names as are
returned from @code{gdb.Architecture.name}
(@pxref{gdbpy_architecture_name,,Architecture.name}).
@end defun

@anchor{gdbpy_connections}
@defun gdb.connections
Return a list of @code{gdb.TargetConnection} objects, one for each
currently active connection (@pxref{Connections In Python}).  The
connection objects are in no particular order in the returned list.
@end defun

@defun gdb.format_address (address @r{[}, progspace, architecture@r{]})
Return a string in the format @samp{@var{addr}
<@var{symbol}+@var{offset}>}, where @var{addr} is @var{address}
formatted in hexadecimal, @var{symbol} is the symbol whose address is
the nearest to @var{address} and below it in memory, and @var{offset}
is the offset from @var{symbol} to @var{address} in decimal.

If no suitable @var{symbol} was found, then the
<@var{symbol}+@var{offset}> part is not included in the returned
string, instead the returned string will just contain the
@var{address} formatted as hexadecimal.  How far @value{GDBN} looks
back for a suitable symbol can be controlled with @kbd{set print
max-symbolic-offset} (@pxref{Print Settings}).

Additionally, the returned string can include file name and line
number information when @kbd{set print symbol-filename on}
(@pxref{Print Settings}), in this case the format of the returned
string is @samp{@var{addr} <@var{symbol}+@var{offset}> at
@var{filename}:@var{line-number}}.


The @var{progspace} is the gdb.Progspace in which @var{symbol} is
looked up, and @var{architecture} is used when formatting @var{addr},
e.g.@: in order to determine the size of an address in bytes.

If neither @var{progspace} or @var{architecture} are passed, then by
default @value{GDBN} will use the program space and architecture of
the currently selected inferior, thus, the following two calls are
equivalent:

@smallexample
gdb.format_address(address)
gdb.format_address(address,
                   gdb.selected_inferior().progspace,
                   gdb.selected_inferior().architecture())
@end smallexample

It is not valid to only pass one of @var{progspace} or
@var{architecture}, either they must both be provided, or neither must
be provided (and the defaults will be used).

This method uses the same mechanism for formatting address, symbol,
and offset information as core @value{GDBN} does in commands such as
@kbd{disassemble}.

Here are some examples of the possible string formats:

@smallexample
0x00001042
0x00001042 <symbol+16>
0x00001042 <symbol+16 at file.c:123>
@end smallexample
@end defun

@defun gdb.current_language ()
Return the name of the current language as a string.  Unlike
@code{gdb.parameter('language')}, this function will never return
@samp{auto}.  If a @code{gdb.Frame} object is available (@pxref{Frames
In Python}), the @code{language} method might be preferable in some
cases, as that is not affected by the user's language setting.
@end defun

@node Threading in GDB
@subsubsection Threading in GDB

@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.  @value{GDBN} provides some
functions to help with this.

@defun gdb.block_signals ()
As mentioned earlier (@pxref{Basic Python}), certain signals must be
delivered to the @value{GDBN} main thread.  The @code{block_signals}
function returns a context manager that will block these signals on
entry.  This can be used when starting a new thread to ensure that the
signals are blocked there, like:

@smallexample
with gdb.block_signals():
   start_new_thread()
@end smallexample
@end defun

@deftp {class} gdb.Thread
This is a subclass of Python's @code{threading.Thread} class.  It
overrides the @code{start} method to call @code{block_signals}, making
this an easy-to-use drop-in replacement for creating threads that will
work well in @value{GDBN}.
@end deftp

@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}.

Unlike most Python APIs in @value{GDBN}, @code{post_event} is
thread-safe.  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


@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 occurred 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

If a @code{gdb.Value} has array or pointer type, an integer index can
be used to access elements.

@smallexample
result = some_array[23]
@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__ (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__ (val, 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}.

If @var{type} is @code{None} then this version of @code{__init__}
behaves as though @var{type} was not passed at all.
@end defun

@defun Value.assign (rhs)
Assign @var{rhs} to this value, and return @code{None}.  If this value
cannot be assigned to, or if the assignment is invalid for some reason
(for example a type-checking failure), an exception will be thrown.
@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 nibbles
@code{True} if binary values should be displayed in groups of four bits,
known as nibbles.  @code{False} if it shouldn't (@pxref{Print Settings,
set print nibbles}).

@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_characters
Number of string characters to print, @code{0} to follow
@code{max_elements}, or @code{UINT_MAX} to print an unlimited number
of characters (see @code{set print characters} 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.

@item styling
@code{True} if @value{GDBN} should apply styling to the returned
string.  When styling is applied, the returned string might contain
ANSI terminal escape sequences.  Escape sequences will only be
included if styling is turned on, see @ref{Output Styling}.
Additionally, @value{GDBN} only styles some value contents, so not
every output string will contain escape sequences.

When @code{False}, which is the default, no output styling is applied.

@item summary
@code{True} when just a summary should be printed.  In this mode,
scalar values are printed in their entirety, but aggregates such as
structures or unions are omitted.  This mode is used by @code{set
print frame-arguments scalars} (@pxref{Print Settings}).
@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:

@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

Integer types can be found without looking them up by name.
@xref{Architectures In Python}, for the @code{integer_type} method.

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

@defvar Type.is_scalar
This property is @code{True} if the type is a scalar type, otherwise,
this property is @code{False}.  Examples of non-scalar types include
structures, unions, and classes.
@end defvar

@defvar Type.is_signed
For scalar types (those for which @code{Type.is_scalar} is
@code{True}), this property is @code{True} if the type is signed,
otherwise this property is @code{False}.

Attempting to read this property for a non-scalar type (a type for
which @code{Type.is_scalar} is @code{False}), will raise a
@code{ValueError}.
@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 (n1 @r{[}, 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 (n1 @r{[}, 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.

@vindex TYPE_CODE_XMETHOD
@item gdb.TYPE_CODE_XMETHOD
A method internal to @value{GDBN}.  This is the type used to represent
xmethods (@pxref{Writing an Xmethod}).

@vindex TYPE_CODE_FIXED_POINT
@item gdb.TYPE_CODE_FIXED_POINT
A fixed-point number.

@vindex TYPE_CODE_NAMESPACE
@item gdb.TYPE_CODE_NAMESPACE
A Fortran namelist.
@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}:

@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

Normally, a pretty-printer can respect the user's print settings
(including temporarily applied settings, such as @samp{/x}) simply by
calling @code{Value.format_string} (@pxref{Values From Inferior}).
However, these settings can also be queried directly:

@defun gdb.print_options ()
Return a dictionary whose keys are the valid keywords that can be
given to @code{Value.format_string}, and whose values are the user's
settings.  During a @code{print} or other operation, the values will
reflect any flags that are temporarily in effect.

@smallexample
(gdb) python print (gdb.print_options ()['max_elements'])
200
@end smallexample
@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.

@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
@sc{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 (register)
This method returns the contents of @var{register} in the
frame as a @code{gdb.Value} object.  For a description of the
acceptable values of @var{register} see
@ref{gdbpy_frame_read_register,,Frame.read_register}.  If @var{register}
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}:

@anchor{gdb.PendingFrame.create_unwind_info}
@defun PendingFrame.create_unwind_info (frame_id)
Returns a new @code{gdb.UnwindInfo} instance identified by given
@var{frame_id}.  The @var{frame_id} is used internally by @value{GDBN}
to identify the frames within the current thread's stack.  The
attributes of @var{frame_id} determine what type of frame is
created within @value{GDBN}:

@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 either be an instance of @code{gdb.Value}
or an integer.

A helper class is provided in the @code{gdb.unwinder} module that can
be used to represent a frame-id
(@pxref{gdb.unwinder.FrameId}).

@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

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

@defun PendingFrame.is_valid ()
Returns true if the @code{gdb.PendingFrame} object is valid, false if
not.  A pending frame object becomes invalid when the call to the
unwinder, for which the pending frame was created, returns.

All @code{gdb.PendingFrame} methods, except this one, will raise an
exception if the pending frame object is invalid at the time the
method is called.
@end defun

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

@defun PendingFrame.block ()
Return the pending frame's code block (@pxref{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 raise
a @code{RuntimeError} exception.
@end defun

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

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

@defun PendingFrame.language ()
Return the language of this frame, as a string, or None.
@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 (register, value)
@var{register} 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 The @code{gdb.unwinder} Module

@value{GDBN} comes with a @code{gdb.unwinder} module which contains
the following classes:

@deftp {class} gdb.unwinder.Unwinder
The @code{Unwinder} class is a base class from which user created
unwinders can derive, though it is not required that unwinders derive
from this class, so long as any user created unwinder has the required
@code{name} and @code{enabled} attributes.

@defun gdb.unwinder.Unwinder.__init__(name)
The @var{name} is a string used to reference this unwinder within some
@value{GDBN} commands (@pxref{Managing Registered Unwinders}).
@end defun

@defvar gdb.unwinder.name
A read-only attribute which is a string, the name of this unwinder.
@end defvar

@defvar gdb.unwinder.enabled
A modifiable attribute containing a boolean; when @code{True}, the
unwinder is enabled, and will be used by @value{GDBN}.  When
@code{False}, the unwinder has been disabled, and will not be used.
@end defvar
@end deftp

@anchor{gdb.unwinder.FrameId}
@deftp {class} gdb.unwinder.FrameId
This is a class suitable for being used as the frame-id when calling
@code{gdb.PendingFrame.create_unwind_info}.  It is not required to use
this class, any class with the required attribute
(@pxref{gdb.PendingFrame.create_unwind_info}) will be accepted, but in
most cases this class will be sufficient.

@code{gdb.unwinder.FrameId} has the following method:

@defun gdb.unwinder.FrameId.__init__(sp, pc, special = @code{None})
The @var{sp} and @var{pc} arguments are required and should be either
a @code{gdb.Value} object, or an integer.

The @var{special} argument is optional; if specified, it should be a
@code{gdb.Value} object, or an integer.
@end defun

@code{gdb.unwinder.FrameId} has the following read-only attributes:

@defvar gdb.unwinder.sp
The @var{sp} value passed to the constructor.
@end defvar

@defvar gdb.unwinder.pc
The @var{pc} value passed to the constructor.
@end defvar

@defvar gdb.unwinder.special
The @var{special} value passed to the constructor, or @code{None} if
no such value was passed.
@end defvar
@end deftp

@subheading Registering an Unwinder

Object files and program spaces can have unwinders registered with
them.  In addition, you can register unwinders globally.

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

@defun gdb.unwinder.register_unwinder (locus, unwinder, replace=False)
@var{locus} specifies to which unwinder list to prepend the
@var{unwinder}.  It can be either an object file (@pxref{Objfiles In
Python}), a program space (@pxref{Progspaces In Python}), or
@code{None}, in which case the unwinder is registered globally.  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 an unwinder with an already existing
name raises an exception unless @var{replace} is @code{True}, in which
case the old unwinder is deleted and the new unwinder is registered in
its place.

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

@subheading Unwinder Skeleton Code

Here is an example of how to structure a user created unwinder:

@smallexample
from gdb.unwinder import Unwinder, FrameId

class MyUnwinder(Unwinder):
    def __init__(self):
        super().__init___("MyUnwinder_Name")

    def __call__(self, pending_frame):
        if not <we recognize frame>:
            return None

        # Create a FrameID.  Usually the frame is identified by a
        # stack pointer and the function address.
        sp = ... compute a stack address ...
        pc = ... compute function address ...
        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-number>, <register-value>)
        ....

        # Return the result:
        return unwind_info

gdb.unwinder.register_unwinder(<locus>, MyUnwinder(), <replace>)
@end smallexample

@anchor{Managing Registered Unwinders}
@subheading Managing Registered Unwinders
@value{GDBN} defines 3 commands to manage registered unwinders.  These
are:

@table @code
@item info unwinder @r{[} @var{locus} @r{[} @var{name-regexp} @r{]} @r{]}
Lists all registered unwinders.  Arguments @var{locus} and
@var{name-regexp} are both optional and can be used to filter which
unwinders are listed.

The @var{locus} argument should be either @kbd{global},
@kbd{progspace}, or the name of an object file.  Only unwinders
registered for the specified locus will be listed.

The @var{name-regexp} is a regular expression used to match against
unwinder names.  When trying to match against unwinder names that
include a string enclose @var{name-regexp} in quotes.
@item disable unwinder @r{[} @var{locus} @r{[} @var{name-regexp} @r{]} @r{]}
The @var{locus} and @var{name-regexp} are interpreted as in @kbd{info
unwinder} above, but instead of listing the matching unwinders, all of
the matching unwinders are disabled.  The @code{enabled} field of each
matching unwinder is set to @code{False}.
@item enable unwinder @r{[} @var{locus} @r{[} @var{name-regexp} @r{]} @r{]}
The @var{locus} and @var{name-regexp} are interpreted as in @kbd{info
unwinder} above, but instead of listing the matching unwinders, all of
the matching unwinders are enabled.  The @code{enabled} field of each
matching unwinder is set to @code{True}.
@end table

@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 @value{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

@anchor{gdbpy_inferior_connection}
@defvar Inferior.connection
The @code{gdb.TargetConnection} for this inferior (@pxref{Connections
In Python}), or @code{None} if this inferior has no connection.
@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}.  This is equivalent to
@code{gdb.Inferior.connection.num} in the case where
@code{gdb.Inferior.connection} is not @code{None}.
@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.main_name
A string holding the name of this inferior's ``main'' function, if it
can be determined.  If the name of main is not known, this is
@code{None}.
@end defvar

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

@defvar Inferior.arguments
The inferior's command line arguments, if known.  This corresponds to
the @code{set args} and @code{show args} commands.  @xref{Arguments}.

When accessed, the value is a string holding all the arguments.  The
contents are quoted as they would be when passed to the shell.  If
there are no arguments, the value is @code{None}.

Either a string or a sequence of strings can be assigned to this
attribute.  When a string is assigned, it is assumed to have any
necessary quoting for the shell; when a sequence is assigned, the
quoting is applied by @value{GDBN}.
@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

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

@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

@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_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


The environment that will be passed to the inferior can be changed
from Python by using the following methods.  These methods only take
effect when the inferior is started -- they will not affect an
inferior that is already executing.

@defun Inferior.clear_env ()
Clear the current environment variables that will be passed to this
inferior.
@end defun

@defun Inferior.set_env (name, value)
Set the environment variable @var{name} to have the indicated value.
Both parameters must be strings.
@end defun

@defun Inferior.unset_env (name)
Unset the environment variable @var{name}.  @var{name} must be a
string.
@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")
    if hasattr (event, 'exit_code'):
        print ("exit code: %d" % (event.exit_code))
    else:
        print ("exit code not available")

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.

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}.  This event is a base class and is never
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}.
@code{gdb.ThreadEvent} holds the following attributes:

@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

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.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 @code{gdb.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 a 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 attribute 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.free_objfile
Emits @code{gdb.FreeObjFileEvent} which indicates that an object file
is about to be removed from @value{GDBN}.  One reason this can happen
is when the inferior calls @code{dlclose}.
@code{gdb.FreeObjFileEvent} has one attribute:

@defvar NewObjFileEvent.objfile
A reference to the object file (@code{gdb.Objfile}) which will be unloaded.
@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 InferiorDeletedEvent.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

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

@defvar ThreadExitedEvent.inferior_thread
The exiting thread.
@end defvar

@item events.gdb_exiting
This is emitted when @value{GDBN} exits.  This event is not emitted if
@value{GDBN} exits as a result of an internal error, or after an
unexpected signal.  The event is of type @code{gdb.GdbExitingEvent},
which has a single attribute:

@defvar GdbExitingEvent.exit_code
An integer, the value of the exit code @value{GDBN} will return.
@end defvar

@item events.connection_removed
This is emitted when @value{GDBN} removes a connection
(@pxref{Connections In Python}).  The event is of type
@code{gdb.ConnectionEvent}.  This has a single read-only attribute:

@defvar ConnectionEvent.connection
The @code{gdb.TargetConnection} that is being removed.
@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:

@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

@anchor{inferior_thread_ptid}
@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

@defvar InferiorThread.details
A string containing target specific thread state information.  The
format of this string varies by target.  If there is no additional
state information for this thread, then this attribute contains
@code{None}.

For example, on a @sc{gnu}/Linux system, a thread that is in the
process of exiting will return the string @samp{Exiting}.  For remote
targets the @code{details} string will be obtained with the
@samp{qThreadExtraInfo} remote packet, if the target supports it
(@pxref{qThreadExtraInfo,,@samp{qThreadExtraInfo}}).

@value{GDBN} displays the @code{details} string as part of the
@samp{Target Id} column, in the @code{info threads} output
(@pxref{info_threads,,@samp{info threads}}).
@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 @code{memoryview} object holding the raw instruction data.
@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 occurred 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 CLI Commands In Python
@subsubsection CLI Commands In Python

@cindex CLI commands in python
@cindex commands in python, CLI
@cindex python commands, CLI
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, command_class @r{[}, completer_class @r{[}, 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 at some point in
its @code{invoke} method (normally this is done early in case of
exception).  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{Location Specifications}.

@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 GDB/MI Commands In Python
@subsubsection @sc{gdb/mi} Commands In Python

@cindex MI commands in python
@cindex commands in python, GDB/MI
@cindex python commands, GDB/MI
It is possible to add @sc{gdb/mi} (@pxref{GDB/MI}) commands
implemented in Python.  A @sc{gdb/mi} command is implemented using an
instance of the @code{gdb.MICommand} class, most commonly using a
subclass.

@defun MICommand.__init__ (name)
The object initializer for @code{MICommand} 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.  It must be a valid name of a
@sc{gdb/mi} command, and in particular must start with a hyphen
(@code{-}).  Reusing the name of a built-in @sc{gdb/mi} is not
allowed, and a @code{RuntimeError} will be raised.  Using the name
of an @sc{gdb/mi} command previously defined in Python is allowed, the
previous command will be replaced with the new command.
@end defun

@defun MICommand.invoke (arguments)
This method is called by @value{GDBN} when the new MI command is
invoked.

@var{arguments} is a list of strings.  Note, that @code{--thread}
and @code{--frame} arguments are handled by @value{GDBN} itself therefore
they do not show up in @code{arguments}.

If this method raises an exception, then it is turned into a
@sc{gdb/mi} @code{^error} response.  Only @code{gdb.GdbError}
exceptions (or its sub-classes) should be used for reporting errors to
users, any other exception type is treated as a failure of the
@code{invoke} method, and the exception will be printed to the error
stream according to the @kbd{set python print-stack} setting
(@pxref{set_python_print_stack,,@kbd{set python print-stack}}).

If this method returns @code{None}, then the @sc{gdb/mi} command will
return a @code{^done} response with no additional values.

Otherwise, the return value must be a dictionary, which is converted
to a @sc{gdb/mi} @var{result-record} (@pxref{GDB/MI Output Syntax}).
The keys of this dictionary must be strings, and are used as
@var{variable} names in the @var{result-record}, these strings must
comply with the naming rules detailed below.  The values of this
dictionary are recursively handled as follows:

@itemize
@item
If the value is Python sequence or iterator, it is converted to
@sc{gdb/mi} @var{list} with elements converted recursively.

@item
If the value is Python dictionary, it is converted to
@sc{gdb/mi} @var{tuple}.  Keys in that dictionary must be strings,
which comply with the @var{variable} naming rules detailed below.
Values are converted recursively.

@item
Otherwise, value is first converted to a Python string using
@code{str ()} and then converted to @sc{gdb/mi} @var{const}.
@end itemize

The strings used for @var{variable} names in the @sc{gdb/mi} output
must follow the following rules; the string must be at least one
character long, the first character must be in the set
@code{[a-zA-Z]}, while every subsequent character must be in the set
@code{[-_a-zA-Z0-9]}.
@end defun

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

@defvar MICommand.name
A string, the name of this @sc{gdb/mi} command, as was passed to the
@code{__init__} method.  This attribute is read-only.
@end defvar

@defvar MICommand.installed
A boolean value indicating if this command is installed ready for a
user to call from the command line.  Commands are automatically
installed when they are instantiated, after which this attribute will
be @code{True}.

If later, a new command is created with the same name, then the
original command will become uninstalled, and this attribute will be
@code{False}.

This attribute is read-write, setting this attribute to @code{False}
will uninstall the command, removing it from the set of available
commands.  Setting this attribute to @code{True} will install the
command for use.  If there is already a Python command with this name
installed, the currently installed command will be uninstalled, and
this command installed in its stead.
@end defvar

The following code snippet shows how some trivial MI commands can be
implemented in Python:

@smallexample
class MIEcho(gdb.MICommand):
    """Echo arguments passed to the command."""

    def __init__(self, name, mode):
        self._mode = mode
        super(MIEcho, self).__init__(name)

    def invoke(self, argv):
        if self._mode == 'dict':
            return @{ 'dict': @{ 'argv' : argv @} @}
        elif self._mode == 'list':
            return @{ 'list': argv @}
        else:
            return @{ 'string': ", ".join(argv) @}


MIEcho("-echo-dict", "dict")
MIEcho("-echo-list", "list")
MIEcho("-echo-string", "string")
@end smallexample

The last three lines instantiate the class three times, creating three
new @sc{gdb/mi} commands @code{-echo-dict}, @code{-echo-list}, and
@code{-echo-string}.  Each time a subclass of @code{gdb.MICommand} is
instantiated, the new command is automatically registered with
@value{GDBN}.

Depending on how the Python code is read into @value{GDBN}, you may
need to import the @code{gdb} module explicitly.

The following example shows a @value{GDBN} session in which the above
commands have been added:

@smallexample
(@value{GDBP})
-echo-dict abc def ghi
^done,dict=@{argv=["abc","def","ghi"]@}
(@value{GDBP})
-echo-list abc def ghi
^done,list=["abc","def","ghi"]
(@value{GDBP})
-echo-string abc def ghi
^done,string="abc, def, ghi"
(@value{GDBP})
@end smallexample

Conversely, it is possible to execute @sc{gdb/mi} commands from
Python, with the results being a Python object and not a
specially-formatted string.  This is done with the
@code{gdb.execute_mi} function.

@defun gdb.execute_mi (command @r{[}, arg @r{]}@dots{})
Invoke a @sc{gdb/mi} command.  @var{command} is the name of the
command, a string.  The arguments, @var{arg}, are passed to the
command.  Each argument must also be a string.

This function returns a Python dictionary whose contents reflect the
corresponding @sc{GDB/MI} command's output.  Refer to the
documentation for these commands for details.  Lists are represented
as Python lists, and tuples are represented as Python dictionaries.

If the command fails, it will raise a Python exception.
@end defun

Here is how this works using the commands from the example above:

@smallexample
(@value{GDBP}) python print(gdb.execute_mi("-echo-dict", "abc", "def", "ghi"))
@{'dict': @{'argv': ['abc', 'def', 'ghi']@}@}
(@value{GDBP}) python print(gdb.execute_mi("-echo-list", "abc", "def", "ghi"))
@{'list': ['abc', 'def', 'ghi']@}
(@value{GDBP}) python print(gdb.execute_mi("-echo-string", "abc", "def", "ghi"))
@{'string': 'abc, def, ghi'@}
@end smallexample

@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, command_class, parameter_class @r{[}, 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{CLI 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 includes the Python documentation
string from the parameter's class, if there is one.  If there is no
documentation string, a default value is used.  The documentation
string is included in the output of the parameters @code{help set} and
@code{help show} commands, and should be written taking this into
account.
@end defun

@defvar Parameter.set_doc
If this attribute exists, and is a string, then its value is used as
the first part of the help text for this parameter's @code{set}
command.  The second part of the help text is taken from the
documentation string for the parameter's class, if there is one.

The value of @code{set_doc} should give a brief summary specific to
the set action, this text is only displayed when the user runs the
@code{help set} command for this parameter.  The class documentation
should be used to give a fuller description of what the parameter
does, this text is displayed for both the @code{help set} and
@code{help show} commands.

The @code{set_doc} 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 first part of the help text for this parameter's @code{show}
command.  The second part of the help text is taken from the
documentation string for the parameter's class, if there is one.

The value of @code{show_doc} should give a brief summary specific to
the show action, this text is only displayed when the user runs the
@code{help show} command for this parameter.  The class documentation
should be used to give a fuller description of what the parameter
does, this text is displayed for both the @code{help set} and
@code{help show} commands.

The @code{show_doc} 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 @code{None} should be
interpreted to mean ``unlimited'' (literal @code{'unlimited'} can also
be used to set that value), and the value of 0 is reserved and should
not be used.

@findex PARAM_INTEGER
@findex gdb.PARAM_INTEGER
@item gdb.PARAM_INTEGER
The value is a signed integer.  The value of @code{None} should be
interpreted to mean ``unlimited'' (literal @code{'unlimited'} can also
be used to set that value), and the value of 0 is reserved and should
not be used.

@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 a signed integer.  This is like @code{PARAM_INTEGER},
except that 0 is allowed and the value of @code{None} is not supported.

@findex PARAM_ZUINTEGER
@findex gdb.PARAM_ZUINTEGER
@item gdb.PARAM_ZUINTEGER
The value is an unsigned integer.  This is like @code{PARAM_UINTEGER},
except that 0 is allowed and the value of @code{None} is not supported.

@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_INTEGER}
including that the value of @code{None} should be interpreted to mean
``unlimited'' (literal @code{'unlimited'} can also be used to set that
value), except that 0 is allowed, and the value cannot be negative,
except the special value -1 is returned for the setting of ``unlimited''.

@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 (*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:

@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

@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:

@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

@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

@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

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

@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

@defun Progspace.objfile_for_address (address)
Return the @code{gdb.Objfile} holding the given address, or
@code{None} if no objfile covers it.
@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:

@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

@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

@defun gdb.lookup_objfile (name @r{[}, by_build_id@r{]})
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.is_file
An objfile often comes from an ordinary file, but in some cases it may
be constructed from the contents of memory.  This attribute is
@code{True} for file-backed objfiles, and @code{False} for other
kinds.
@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:

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

@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

@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 occurred: %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.  If this is the oldest frame,
return @code{None}.
@end defun

@defun Frame.newer ()
Return the frame called by this frame.  If this is the newest frame,
return @code{None}.
@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

@defun Frame.language ()
Return a string, the source language for this frame.
@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:

@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:

@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

@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

@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

@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.locations
Get the most current list of breakpoint locations that are inserted for this
breakpoint, with elements of type @code{gdb.BreakpointLocation}
(described below).  This functionality matches that of the
@code{info breakpoint} command (@pxref{Set Breaks}), in that it only retrieves
the most current list of locations, thus the list itself when returned is
not updated behind the scenes.  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

@subheading Breakpoint Locations

A breakpoint location is one of the actual places where a breakpoint has been
set, represented in the Python API by the @code{gdb.BreakpointLocation}
type.  This type is never instantiated by the user directly, but is retrieved
from @code{Breakpoint.locations} which returns a list of breakpoint
locations where it is currently set.  Breakpoint locations can become
invalid if new symbol files are loaded or dynamically loaded libraries are
closed.  Accessing the attributes of an invalidated breakpoint location will
throw a @code{RuntimeError} exception.  Access the @code{Breakpoint.locations}
attribute again to retrieve the new and valid breakpoints location list.

@defvar BreakpointLocation.source
This attribute returns the source file path and line number where this location
was set. The type of the attribute is a tuple of @var{string} and
@var{long}.  If the breakpoint location doesn't have a source location,
it returns None, which is the case for watchpoints and catchpoints.
This will throw a @code{RuntimeError} exception if the location
has been invalidated. This attribute is not writable.
@end defvar

@defvar BreakpointLocation.address
This attribute returns the address where this location was set.
This attribute is of type long.  This will throw a @code{RuntimeError}
exception if the location has been invalidated.  This attribute is
not writable.
@end defvar

@defvar BreakpointLocation.enabled
This attribute holds the value for whether or not this location is enabled.
This attribute is writable (boolean).  This will throw a @code{RuntimeError}
exception if the location has been invalidated.
@end defvar

@defvar BreakpointLocation.owner
This attribute holds a reference to the @code{gdb.Breakpoint} owner object,
from which this @code{gdb.BreakpointLocation} was retrieved from.
This will throw a @code{RuntimeError} exception if the location has been
invalidated.  This attribute is not writable.
@end defvar

@defvar BreakpointLocation.function
This attribute gets the name of the function where this location was set.
If no function could be found this attribute returns @code{None}.
This will throw a @code{RuntimeError} exception if the location has
been invalidated.  This attribute is not writable.
@end defvar

@defvar BreakpointLocation.fullname
This attribute gets the full name of where this location was set.  If no
full name could be found, this attribute returns @code{None}.
This will throw a @code{RuntimeError} exception if the location has
been invalidated.  This attribute is not writable.
@end defvar

@defvar BreakpointLocation.thread_groups
This attribute gets the thread groups it was set in.  It returns a @code{List}
of the thread group ID's.  This will throw a @code{RuntimeError}
exception if the location has been invalidated.  This attribute
is not 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:

@anchor{gdbpy_architecture_name}
@defun Architecture.name ()
Return the name (string value) of the architecture.
@end defun

@defun Architecture.disassemble (start_pc @r{[}, end_pc @r{[}, 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

@defun Architecture.integer_type (size @r{[}, signed@r{]})
This function looks up an integer type by its @var{size}, and
optionally whether or not it is signed.

@var{size} is the size, in bits, of the desired integer type.  Only
certain sizes are currently supported: 0, 8, 16, 24, 32, 64, and 128.

If @var{signed} is not specified, it defaults to @code{True}.  If
@var{signed} is @code{False}, the returned type will be unsigned.

If the indicated type cannot be found, this function will throw a
@code{ValueError} exception.
@end defun

@anchor{gdbpy_architecture_registers}
@defun Architecture.registers (@r{[} 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 (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 Connections In Python
@subsubsection Connections In Python
@cindex connections in python
@value{GDBN} lets you run and debug multiple programs in a single
session.  Each program being debugged has a connection, the connection
describes how @value{GDBN} controls the program being debugged.
Examples of different connection types are @samp{native} and
@samp{remote}.  @xref{Inferiors Connections and Programs}.

Connections in @value{GDBN} are represented as instances of
@code{gdb.TargetConnection}, or as one of its sub-classes.  To get a
list of all connections use @code{gdb.connections}
(@pxref{gdbpy_connections,,gdb.connections}).

To get the connection for a single @code{gdb.Inferior} read its
@code{gdb.Inferior.connection} attribute
(@pxref{gdbpy_inferior_connection,,gdb.Inferior.connection}).

Currently there is only a single sub-class of
@code{gdb.TargetConnection}, @code{gdb.RemoteTargetConnection},
however, additional sub-classes may be added in future releases of
@value{GDBN}.  As a result you should avoid writing code like:

@smallexample
conn = gdb.selected_inferior().connection
if type(conn) is gdb.RemoteTargetConnection:
  print("This is a remote target connection")
@end smallexample

@noindent
as this may fail when more connection types are added.  Instead, you
should write:

@smallexample
conn = gdb.selected_inferior().connection
if isinstance(conn, gdb.RemoteTargetConnection):
  print("This is a remote target connection")
@end smallexample

A @code{gdb.TargetConnection} has the following method:

@defun TargetConnection.is_valid ()
Return @code{True} if the @code{gdb.TargetConnection} object is valid,
@code{False} if not.  A @code{gdb.TargetConnection} will become
invalid if the connection no longer exists within @value{GDBN}, this
might happen when no inferiors are using the connection, but could be
delayed until the user replaces the current target.

Reading any of the @code{gdb.TargetConnection} properties will throw
an exception if the connection is invalid.
@end defun

A @code{gdb.TargetConnection} has the following read-only properties:

@defvar TargetConnection.num
An integer assigned by @value{GDBN} to uniquely identify this
connection.  This is the same value as displayed in the @samp{Num}
column of the @code{info connections} command output (@pxref{Inferiors
Connections and Programs,,info connections}).
@end defvar

@defvar TargetConnection.type
A string that describes what type of connection this is.  This string
will be one of the valid names that can be passed to the @code{target}
command (@pxref{Target Commands,,target command}).
@end defvar

@defvar TargetConnection.description
A string that gives a short description of this target type.  This is
the same string that is displayed in the @samp{Description} column of
the @code{info connection} command output (@pxref{Inferiors
Connections and Programs,,info connections}).
@end defvar

@defvar TargetConnection.details
An optional string that gives additional information about this
connection.  This attribute can be @code{None} if there are no
additional details for this connection.

An example of a connection type that might have additional details is
the @samp{remote} connection, in this case the details string can
contain the @samp{@var{hostname}:@var{port}} that was used to connect
to the remote target.
@end defvar

The @code{gdb.RemoteTargetConnection} class is a sub-class of
@code{gdb.TargetConnection}, and is used to represent @samp{remote}
and @samp{extended-remote} connections.  In addition to the attributes
and methods available from the @code{gdb.TargetConnection} base class,
a @code{gdb.RemoteTargetConnection} has the following method:

@kindex maint packet
@defun RemoteTargetConnection.send_packet (packet)
This method sends @var{packet} to the remote target and returns the
response.  The @var{packet} should either be a @code{bytes} object, or
a @code{Unicode} string.

If @var{packet} is a @code{Unicode} string, then the string is encoded
to a @code{bytes} object using the @sc{ascii} codec.  If the string
can't be encoded then an @code{UnicodeError} is raised.

If @var{packet} is not a @code{bytes} object, or a @code{Unicode}
string, then a @code{TypeError} is raised.  If @var{packet} is empty
then a @code{ValueError} is raised.

The response is returned as a @code{bytes} object.  If it is known
that the response can be represented as a string then this can be
decoded from the buffer.  For example, if it is known that the
response is an @sc{ascii} string:

@smallexample
remote_connection.send_packet("some_packet").decode("ascii")
@end smallexample

The prefix, suffix, and checksum (as required by the remote serial
protocol) are automatically added to the outgoing packet, and removed
from the incoming packet before the contents of the reply are
returned.

This is equivalent to the @code{maintenance packet} command
(@pxref{maint packet}).
@end defun

@node TUI Windows In Python
@subsubsection Implementing new TUI windows
@cindex Python TUI Windows

New TUI (@pxref{TUI}) windows can be implemented in Python.

@defun gdb.register_window_type (name, 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.  The @var{name} should match the regular expression
@code{[a-zA-Z][-_.a-zA-Z0-9]*}, it is an error to try and create a
window with an invalid name.

@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 (string @r{[}, 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 (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 (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 (x, y, 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, from the top left
corner), and @var{button} specifies which mouse button was used, whose
values can be 1 (left), 2 (middle), or 3 (right).
@end defun

@node Disassembly In Python
@subsubsection Instruction Disassembly In Python
@cindex python instruction disassembly

@value{GDBN}'s builtin disassembler can be extended, or even replaced,
using the Python API.  The disassembler related features are contained
within the @code{gdb.disassembler} module:

@anchor{DisassembleInfo Class}
@deftp {class} gdb.disassembler.DisassembleInfo
Disassembly is driven by instances of this class.  Each time
@value{GDBN} needs to disassemble an instruction, an instance of this
class is created and passed to a registered disassembler.  The
disassembler is then responsible for disassembling an instruction and
returning a result.

Instances of this type are usually created within @value{GDBN},
however, it is possible to create a copy of an instance of this type,
see the description of @code{__init__} for more details.

This class has the following properties and methods:

@defvar DisassembleInfo.address
A read-only integer containing the address at which @value{GDBN}
wishes to disassemble a single instruction.
@end defvar

@defvar DisassembleInfo.architecture
The @code{gdb.Architecture} (@pxref{Architectures In Python}) for
which @value{GDBN} is currently disassembling, this property is
read-only.
@end defvar

@defvar DisassembleInfo.progspace
The @code{gdb.Progspace} (@pxref{Progspaces In Python,,Program Spaces
In Python}) for which @value{GDBN} is currently disassembling, this
property is read-only.
@end defvar

@defun DisassembleInfo.is_valid ()
Returns @code{True} if the @code{DisassembleInfo} object is valid,
@code{False} if not.  A @code{DisassembleInfo} object will become
invalid once the disassembly call for which the @code{DisassembleInfo}
was created, has returned.  Calling other @code{DisassembleInfo}
methods, or accessing @code{DisassembleInfo} properties, will raise a
@code{RuntimeError} exception if it is invalid.
@end defun

@defun DisassembleInfo.__init__ (info)
This can be used to create a new @code{DisassembleInfo} object that is
a copy of @var{info}.  The copy will have the same @code{address},
@code{architecture}, and @code{progspace} values as @var{info}, and
will become invalid at the same time as @var{info}.

This method exists so that sub-classes of @code{DisassembleInfo} can
be created, these sub-classes must be initialized as copies of an
existing @code{DisassembleInfo} object, but sub-classes might choose
to override the @code{read_memory} method, and so control what
@value{GDBN} sees when reading from memory
(@pxref{builtin_disassemble}).
@end defun

@defun DisassembleInfo.read_memory (length, offset)
This method allows the disassembler to read the bytes of the
instruction to be disassembled.  The method reads @var{length} bytes,
starting at @var{offset} from
@code{DisassembleInfo.address}.

It is important that the disassembler read the instruction bytes using
this method, rather than reading inferior memory directly, as in some
cases @value{GDBN} disassembles from an internal buffer rather than
directly from inferior memory, calling this method handles this
detail.

Returns a buffer object, which behaves much like an array or a string,
just as @code{Inferior.read_memory} does
(@pxref{gdbpy_inferior_read_memory,,Inferior.read_memory}).  The
length of the returned buffer will always be exactly @var{length}.

If @value{GDBN} is unable to read the required memory then a
@code{gdb.MemoryError} exception is raised (@pxref{Exception
Handling}).

This method can be overridden by a sub-class in order to control what
@value{GDBN} sees when reading from memory
(@pxref{builtin_disassemble}).  When overriding this method it is
important to understand how @code{builtin_disassemble} makes use of
this method.

While disassembling a single instruction there could be multiple calls
to this method, and the same bytes might be read multiple times.  Any
single call might only read a subset of the total instruction bytes.

If an implementation of @code{read_memory} is unable to read the
requested memory contents, for example, if there's a request to read
from an invalid memory address, then a @code{gdb.MemoryError} should
be raised.

Raising a @code{MemoryError} inside @code{read_memory} does not
automatically mean a @code{MemoryError} will be raised by
@code{builtin_disassemble}.  It is possible the @value{GDBN}'s builtin
disassembler is probing to see how many bytes are available.  When
@code{read_memory} raises the @code{MemoryError} the builtin
disassembler might be able to perform a complete disassembly with the
bytes it has available, in this case @code{builtin_disassemble} will
not itself raise a @code{MemoryError}.

Any other exception type raised in @code{read_memory} will propagate
back and be re-raised by @code{builtin_disassemble}.
@end defun

@defun DisassembleInfo.text_part (style, string)
Create a new @code{DisassemblerTextPart} representing a piece of a
disassembled instruction.  @var{string} should be a non-empty string,
and @var{style} should be an appropriate style constant
(@pxref{Disassembler Style Constants}).

Disassembler parts are used when creating a @code{DisassemblerResult}
in order to represent the styling within an instruction
(@pxref{DisassemblerResult Class}).
@end defun

@defun DisassembleInfo.address_part (address)
Create a new @code{DisassemblerAddressPart}.  @var{address} is the
value of the absolute address this part represents.  A
@code{DisassemblerAddressPart} is displayed as an absolute address and
an associated symbol, the address and symbol are styled appropriately.
@end defun

@end deftp

@anchor{Disassembler Class}
@deftp {class} gdb.disassembler.Disassembler
This is a base class from which all user implemented disassemblers
must inherit.

@defun Disassembler.__init__ (name)
The constructor takes @var{name}, a string, which should be a short
name for this disassembler.
@end defun

@defun Disassembler.__call__ (info)
The @code{__call__} method must be overridden by sub-classes to
perform disassembly.  Calling @code{__call__} on this base class will
raise a @code{NotImplementedError} exception.

The @var{info} argument is an instance of @code{DisassembleInfo}, and
describes the instruction that @value{GDBN} wants disassembling.

If this function returns @code{None}, this indicates to @value{GDBN}
that this sub-class doesn't wish to disassemble the requested
instruction.  @value{GDBN} will then use its builtin disassembler to
perform the disassembly.

Alternatively, this function can return a @code{DisassemblerResult}
that represents the disassembled instruction, this type is described
in more detail below.

The @code{__call__} method can raise a @code{gdb.MemoryError}
exception (@pxref{Exception Handling}) to indicate to @value{GDBN}
that there was a problem accessing the required memory, this will then
be displayed by @value{GDBN} within the disassembler output.

Ideally, the only three outcomes from invoking @code{__call__} would
be a return of @code{None}, a successful disassembly returned in a
@code{DisassemblerResult}, or a @code{MemoryError} indicating that
there was a problem reading memory.

However, as an implementation of @code{__call__} could fail due to
other reasons, e.g.@: some external resource required to perform
disassembly is temporarily unavailable, then, if @code{__call__}
raises a @code{GdbError}, the exception will be converted to a string
and printed at the end of the disassembly output, the disassembly
request will then stop.

Any other exception type raised by the @code{__call__} method is
considered an error in the user code, the exception will be printed to
the error stream according to the @kbd{set python print-stack} setting
(@pxref{set_python_print_stack,,@kbd{set python print-stack}}).
@end defun
@end deftp

@anchor{DisassemblerResult Class}
@deftp {class} gdb.disassembler.DisassemblerResult
This class represents the result of disassembling a single
instruction.  An instance of this class will be returned from
@code{builtin_disassemble} (@pxref{builtin_disassemble}), and an
instance of this class should be returned from
@w{@code{Disassembler.__call__}} (@pxref{Disassembler Class}) if an
instruction was successfully disassembled.

It is not possible to sub-class the @code{DisassemblerResult} class.

The @code{DisassemblerResult} class has the following properties and
methods:

@defun DisassemblerResult.__init__ (length, string, parts)
Initialize an instance of this class, @var{length} is the length of
the disassembled instruction in bytes, which must be greater than
zero.

Only one of @var{string} or @var{parts} should be used to initialize a
new @code{DisassemblerResult}; the other one should be passed the
value @code{None}.  Alternatively, the arguments can be passed by
name, and the unused argument can be ignored.

The @var{string} argument, if not @code{None}, is a non-empty string
that represents the entire disassembled instruction.  Building a result
object using the @var{string} argument does not allow for any styling
information to be included in the result.  @value{GDBN} will style the
result as a single @code{DisassemblerTextPart} with @code{STYLE_TEXT}
style (@pxref{Disassembler Styling Parts}).

The @var{parts} argument, if not @code{None}, is a non-empty sequence
of @code{DisassemblerPart} objects.  Each part represents a small part
of the disassembled instruction along with associated styling
information.  A result object built using @var{parts} can be displayed
by @value{GDBN} with full styling information
(@pxref{style_disassembler_enabled,,@kbd{set style disassembler
enabled}}).
@end defun

@defvar DisassemblerResult.length
A read-only property containing the length of the disassembled
instruction in bytes, this will always be greater than zero.
@end defvar

@defvar DisassemblerResult.string
A read-only property containing a non-empty string representing the
disassembled instruction.  The @var{string} is a representation of the
disassembled instruction without any styling information.  To see how
the instruction will be styled use the @var{parts} property.

If this instance was initialized using separate
@code{DisassemblerPart} objects, the @var{string} property will still
be valid.  The @var{string} value is created by concatenating the
@code{DisassemblerPart.string} values of each component part
(@pxref{Disassembler Styling Parts}).
@end defvar

@defvar DisassemblerResult.parts
A read-only property containing a non-empty sequence of
@code{DisassemblerPart} objects.  Each @code{DisassemblerPart} object
contains a small part of the instruction along with information about
how that part should be styled.  @value{GDBN} uses this information to
create styled disassembler output
(@pxref{style_disassembler_enabled,,@kbd{set style disassembler
enabled}}).

If this instance was initialized using a single string rather than
with a sequence of @code{DisassemblerPart} objects, the @var{parts}
property will still be valid.  In this case the @var{parts} property
will hold a sequence containing a single @code{DisassemblerTextPart}
object, the string of which will represent the entire instruction, and
the style of which will be @code{STYLE_TEXT}.
@end defvar
@end deftp

@anchor{Disassembler Styling Parts}
@deftp {class} gdb.disassembler.DisassemblerPart
This is a parent class from which the different part sub-classes
inherit.  Only instances of the sub-classes detailed below will be
returned by the Python API.

It is not possible to directly create instances of either this parent
class, or any of the sub-classes listed below.  Instances of the
sub-classes listed below are created by calling
@code{builtin_disassemble} (@pxref{builtin_disassemble}) and are
returned within the @code{DisassemblerResult} object, or can be
created by calling the @code{text_part} and @code{address_part}
methods on the @code{DisassembleInfo} class (@pxref{DisassembleInfo
Class}).

The @code{DisassemblerPart} class has a single property:

@defvar DisassemblerPart.string
A read-only property that contains a non-empty string representing
this part of the disassembled instruction.  The string within this
property doesn't include any styling information.
@end defvar
@end deftp

@deftp {class} gdb.disassembler.DisassemblerTextPart
The @code{DisassemblerTextPart} class represents a piece of the
disassembled instruction and the associated style for that piece.
Instances of this class can't be created directly, instead call
@code{DisassembleInfo.text_part} to create a new instance of this
class (@pxref{DisassembleInfo Class}).

As well as the properties of its parent class, the
@code{DisassemblerTextPart} has the following additional property:

@defvar DisassemblerTextPart.style
A read-only property that contains one of the defined style constants.
@value{GDBN} will use this style when styling this part of the
disassembled instruction (@pxref{Disassembler Style Constants}).
@end defvar
@end deftp

@deftp {class} gdb.disassembler.DisassemblerAddressPart
The @code{DisassemblerAddressPart} class represents an absolute
address within a disassembled instruction.  Using a
@code{DisassemblerAddressPart} instead of a
@code{DisassemblerTextPart} with @code{STYLE_ADDRESS} is preferred,
@value{GDBN} will display the address as both an absolute address, and
will look up a suitable symbol to display next to the address.  Using
@code{DisassemblerAddressPart} also ensures that user settings such as
@code{set print max-symbolic-offset} are respected.

Here is an example of an x86-64 instruction:

@smallexample
call   0x401136 <foo>
@end smallexample

@noindent
In this instruction the @code{0x401136 <foo>} was generated from a
single @code{DisassemblerAddressPart}.  The @code{0x401136} will be
styled with @code{STYLE_ADDRESS}, and @code{foo} will be styled with
@code{STYLE_SYMBOL}.  The @code{<} and @code{>} will be styled as
@code{STYLE_TEXT}.

If the inclusion of the symbol name is not required then a
@code{DisassemblerTextPart} with style @code{STYLE_ADDRESS} can be
used instead.

Instances of this class can't be created directly, instead call
@code{DisassembleInfo.address_part} to create a new instance of this
class (@pxref{DisassembleInfo Class}).

As well as the properties of its parent class, the
@code{DisassemblerAddressPart} has the following additional property:

@defvar DisassemblerAddressPart.address
A read-only property that contains the @var{address} passed to this
object's @code{__init__} method.
@end defvar
@end deftp

@anchor{Disassembler Style Constants}

The following table lists all of the disassembler styles that are
available.  @value{GDBN} maps these style constants onto its style
settings (@pxref{Output Styling}).  In some cases, several style
constants produce the same style settings, and thus will produce the
same visual effect on the screen.  This could change in future
releases of @value{GDBN}, so care should be taken to select the
correct style constant to ensure correct output styling in future
releases of @value{GDBN}.

@vtable @code
@vindex STYLE_TEXT
@item gdb.disassembler.STYLE_TEXT
This is the default style used by @value{GDBN} when styling
disassembler output.  This style should be used for any parts of the
instruction that don't fit any of the other styles listed below.
@value{GDBN} styles text with this style using its default style.

@vindex STYLE_MNEMONIC
@item gdb.disassembler.STYLE_MNEMONIC
This style is used for styling the primary instruction mnemonic, which
usually appears at, or near, the start of the disassembled instruction
string.

@value{GDBN} styles text with this style using the @code{disassembler
mnemonic} style setting.

@vindex STYLE_SUB_MNEMONIC
@item gdb.disassembler.STYLE_SUB_MNEMONIC
This style is used for styling any sub-mnemonics within a disassembled
instruction.  A sub-mnemonic is any text within the instruction that
controls the function of the instruction, but which is disjoint from
the primary mnemonic (which will have styled @code{STYLE_MNEMONIC}).

As an example, consider this AArch64 instruction:

@smallexample
add	w16, w7, w1, lsl #1
@end smallexample

@noindent
The @code{add} is the primary instruction mnemonic, and would be given
style @code{STYLE_MNEMONIC}, while @code{lsl} is the sub-mnemonic, and
would be given the style @code{STYLE_SUB_MNEMONIC}.

@value{GDBN} styles text with this style using the @code{disassembler
mnemonic} style setting.

@vindex STYLE_ASSEMBLER_DIRECTIVE
@item gdb.disassembler.STYLE_ASSEMBLER_DIRECTIVE
Sometimes a series of bytes doesn't decode to a valid instruction.  In
this case the disassembler may choose to represent the result of
disassembling using an assembler directive, for example:

@smallexample
.word	0x1234
@end smallexample

@noindent
In this case, the @code{.word} would be give the
@code{STYLE_ASSEMBLER_DIRECTIVE} style.  An assembler directive is
similar to a mnemonic in many ways but is something that is not part
of the architecture's instruction set.

@value{GDBN} styles text with this style using the @code{disassembler
mnemonic} style setting.

@vindex STYLE_REGISTER
@item gdb.disassembler.STYLE_REGISTER
This style is used for styling any text that represents a register
name, or register number, within a disassembled instruction.

@value{GDBN} styles text with this style using the @code{disassembler
register} style setting.

@vindex STYLE_ADDRESS
@item gdb.disassembler.STYLE_ADDRESS
This style is used for styling numerical values that represent
absolute addresses within the disassembled instruction.

When creating a @code{DisassemblerTextPart} with this style, you
should consider if a @code{DisassemblerAddressPart} would be more
appropriate.  See @ref{Disassembler Styling Parts} for a description
of what each part offers.

@value{GDBN} styles text with this style using the @code{disassembler
address} style setting.

@vindex STYLE_ADDRESS_OFFSET
@item gdb.disassembler.STYLE_ADDRESS_OFFSET
This style is used for styling numerical values that represent offsets
to addresses within the disassembled instruction.  A value is
considered an address offset when the instruction itself is going to
access memory, and the value is being used to offset which address is
accessed.

For example, an architecture might have an instruction that loads from
memory using an address within a register.  If that instruction also
allowed for an immediate offset to be encoded into the instruction,
this would be an address offset.  Similarly, a branch instruction
might jump to an address in a register plus an address offset that is
encoded into the instruction.

@value{GDBN} styles text with this style using the @code{disassembler
immediate} style setting.

@vindex STYLE_IMMEDIATE
@item gdb.disassembler.STYLE_IMMEDIATE
Use @code{STYLE_IMMEDIATE} for any numerical values within a
disassembled instruction when those values are not addresses, address
offsets, or register numbers (The styles @code{STYLE_ADDRESS},
@code{STYLE_ADDRESS_OFFSET}, or @code{STYLE_REGISTER} can be used in
those cases).

@value{GDBN} styles text with this style using the @code{disassembler
immediate} style setting.

@vindex STYLE_SYMBOL
@item gdb.disassembler.STYLE_SYMBOL
This style is used for styling the textual name of a symbol that is
included within a disassembled instruction.  A symbol name is often
included next to an absolute address within a disassembled instruction
to make it easier for the user to understand what the address is
referring too.  For example:

@smallexample
call   0x401136 <foo>
@end smallexample

@noindent
Here @code{foo} is the name of a symbol, and should be given the
@code{STYLE_SYMBOL} style.

Adding symbols next to absolute addresses like this is handled
automatically by the @code{DisassemblerAddressPart} class
(@pxref{Disassembler Styling Parts}).

@value{GDBN} styles text with this style using the @code{disassembler
symbol} style setting.

@vindex STYLE_COMMENT_START
@item gdb.disassembler.STYLE_COMMENT_START
This style is used to start a line comment in the disassembly output.
Unlike other styles, which only apply to the single
@code{DisassemblerTextPiece} to which they are applied, the comment
style is sticky, and overrides the style of any further pieces within
this instruction.

This means that, after a @code{STYLE_COMMENT_START} piece has been
seen, @value{GDBN} will apply the comment style until the end of the
line, ignoring the specific style within a piece.

@value{GDBN} styles text with this style using the @code{disassembler
comment} style setting.
@end vtable

The following functions are also contained in the
@code{gdb.disassembler} module:

@defun register_disassembler (disassembler, architecture)
The @var{disassembler} must be a sub-class of
@code{gdb.disassembler.Disassembler} or @code{None}.

The optional @var{architecture} is either a string, or the value
@code{None}.  If it is a string, then it should be the name of an
architecture known to @value{GDBN}, as returned either from
@code{gdb.Architecture.name}
(@pxref{gdbpy_architecture_name,,gdb.Architecture.name}), or from
@code{gdb.architecture_names}
(@pxref{gdb_architecture_names,,gdb.architecture_names}).

The @var{disassembler} will be installed for the architecture named by
@var{architecture}, or if @var{architecture} is @code{None}, then
@var{disassembler} will be installed as a global disassembler for use
by all architectures.

@cindex disassembler in Python, global vs.@: specific
@cindex search order for disassembler in Python
@cindex look up of disassembler in Python
@value{GDBN} only records a single disassembler for each architecture,
and a single global disassembler.  Calling
@code{register_disassembler} for an architecture, or for the global
disassembler, will replace any existing disassembler registered for
that @var{architecture} value.  The previous disassembler is returned.

If @var{disassembler} is @code{None} then any disassembler currently
registered for @var{architecture} is deregistered and returned.

When @value{GDBN} is looking for a disassembler to use, @value{GDBN}
first looks for an architecture specific disassembler.  If none has
been registered then @value{GDBN} looks for a global disassembler (one
registered with @var{architecture} set to @code{None}).  Only one
disassembler is called to perform disassembly, so, if there is both an
architecture specific disassembler, and a global disassembler
registered, it is the architecture specific disassembler that will be
used.

@value{GDBN} tracks the architecture specific, and global
disassemblers separately, so it doesn't matter in which order
disassemblers are created or registered; an architecture specific
disassembler, if present, will always be used in preference to a
global disassembler.

You can use the @kbd{maint info python-disassemblers} command
(@pxref{maint info python-disassemblers}) to see which disassemblers
have been registered.
@end defun

@anchor{builtin_disassemble}
@defun builtin_disassemble (info)
This function calls back into @value{GDBN}'s builtin disassembler to
disassemble the instruction identified by @var{info}, an instance, or
sub-class, of @code{DisassembleInfo}.

When the builtin disassembler needs to read memory the
@code{read_memory} method on @var{info} will be called.  By
sub-classing @code{DisassembleInfo} and overriding the
@code{read_memory} method, it is possible to intercept calls to
@code{read_memory} from the builtin disassembler, and to modify the
values returned.

It is important to understand that, even when
@code{DisassembleInfo.read_memory} raises a @code{gdb.MemoryError}, it
is the internal disassembler itself that reports the memory error to
@value{GDBN}.  The reason for this is that the disassembler might
probe memory to see if a byte is readable or not; if the byte can't be
read then the disassembler may choose not to report an error, but
instead to disassemble the bytes that it does have available.

If the builtin disassembler is successful then an instance of
@code{DisassemblerResult} is returned from @code{builtin_disassemble},
alternatively, if something goes wrong, an exception will be raised.

A @code{MemoryError} will be raised if @code{builtin_disassemble} is
unable to read some memory that is required in order to perform
disassembly correctly.

Any exception that is not a @code{MemoryError}, that is raised in a
call to @code{read_memory}, will pass through
@code{builtin_disassemble}, and be visible to the caller.

Finally, there are a few cases where @value{GDBN}'s builtin
disassembler can fail for reasons that are not covered by
@code{MemoryError}.  In these cases, a @code{GdbError} will be raised.
The contents of the exception will be a string describing the problem
the disassembler encountered.
@end defun

Here is an example that registers a global disassembler.  The new
disassembler invokes the builtin disassembler, and then adds a
comment, @code{## Comment}, to each line of disassembly output:

@smallexample
class ExampleDisassembler(gdb.disassembler.Disassembler):
    def __init__(self):
        super().__init__("ExampleDisassembler")

    def __call__(self, info):
        result = gdb.disassembler.builtin_disassemble(info)
        length = result.length
        text = result.string + "\t## Comment"
        return gdb.disassembler.DisassemblerResult(length, text)

gdb.disassembler.register_disassembler(ExampleDisassembler())
@end smallexample

The following example creates a sub-class of @code{DisassembleInfo} in
order to intercept the @code{read_memory} calls, within
@code{read_memory} any bytes read from memory have the two 4-bit
nibbles swapped around.  This isn't a very useful adjustment, but
serves as an example.

@smallexample
class MyInfo(gdb.disassembler.DisassembleInfo):
    def __init__(self, info):
        super().__init__(info)

    def read_memory(self, length, offset):
        buffer = super().read_memory(length, offset)
        result = bytearray()
        for b in buffer:
            v = int.from_bytes(b, 'little')
            v = (v << 4) & 0xf0 | (v >> 4)
            result.append(v)
        return memoryview(result)

class NibbleSwapDisassembler(gdb.disassembler.Disassembler):
    def __init__(self):
        super().__init__("NibbleSwapDisassembler")

    def __call__(self, info):
        info = MyInfo(info)
        return gdb.disassembler.builtin_disassemble(info)

gdb.disassembler.register_disassembler(NibbleSwapDisassembler())
@end smallexample

@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
