@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} installs 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.  When creating a new Python thread, you can
use @code{gdb.block_signals} or @code{gdb.Thread} to handle this
correctly; see @ref{Threading in GDB}.

@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.to_array ()
If this value is array-like (@pxref{Type.is_array_like}), then this
method converts it to an array, which is returned.  If this value is
already an array, it is simply returned.  Otherwise, an exception is
throw.
@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

@defvar Type.is_array_like
@anchor{Type.is_array_like}
A boolean indicating whether this type is array-like.

Some languages have array-like objects that are represented internally
as structures.  For example, this is true for a Rust slice type, or
for an Ada unconstrained array.  @value{GDBN} may know about these
types.  This determination is done based on the language from which
the type originated.
@end defvar

@defvar Type.is_string_like
A boolean indicating whether this type is string-like.  Like
@code{Type.is_array_like}, this is determined based on the originating
language of the type.
@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
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 @value{GDBN}.  You can use this to make
Python breakpoints inferior-specific, for example
(@pxref{python_breakpoint_inferior,,The Breakpoint.inferior
attribute}).
@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 FreeObjFileEvent.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 (@pxref{Thread-Specific
Breakpoints}), this attribute holds the thread's global id.  If the
breakpoint is not thread-specific, this attribute is @code{None}.
This attribute is writable.

Only one of @code{Breakpoint.thread} or @code{Breakpoint.inferior} can
be set to a valid id at any time, that is, a breakpoint can be thread
specific, or inferior specific, but not both.
@end defvar

@anchor{python_breakpoint_inferior}
@defvar Breakpoint.inferior
If the breakpoint is inferior-specific (@pxref{Inferior-Specific
Breakpoints}), this attribute holds the inferior's id.  If the
breakpoint is not inferior-specific, this attribute is @code{None}.

This attribute can be written for breakpoints of type
@code{gdb.BP_BREAKPOINT} and @code{gdb.BP_HARDWARE_BREAKPOINT}.
@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
