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

@node Basic Python
@subsubsection Basic Python

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@findex gdb.set_parameter
@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

@findex gdb.with_parameter
@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

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

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

@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

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

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

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

This function can be useful when implementing a new command
(@pxref{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

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

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

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

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

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

@findex gdb.flush
@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

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

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

@findex gdb.host_charset
@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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

@smallexample
bar = some_val + 2
@end smallexample

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

@smallexample
val3 = val1 + val2
@end smallexample

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

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

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

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

@smallexample
bar = some_val[foo_field]
@end smallexample

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

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

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

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

The following attributes are provided:

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

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

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

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

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

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

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

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

The following methods are provided:

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

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

@smallexample
int *foo;
@end smallexample

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@item nibbles
@code{True} if binary values should be displayed in groups of four bits,
known as nibbles.  @code{False} if it shouldn't (@pxref{Print Settings,
set print nibbles}).

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

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

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

@item max_characters
Number of string characters to print, @code{0} to follow
@code{max_elements}, or @code{UINT_MAX} to print an unlimited number
of characters (see @code{set print characters} in @ref{Print Settings}).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

This method does not return a value.
@end defun


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Attempting to read this property for a non-scalar type (a type for
which @code{Type.is_scalar} is @code{False}), will raise a
@code{ValueError}.
@end defvar

The following methods are provided:

@defun Type.fields ()

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

@itemize @bullet

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

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

@item
Enum types have one field per enum constant.

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

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

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

@end itemize

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@vindex TYPE_CODE_NAMESPACE
@item gdb.TYPE_CODE_NAMESPACE
A Fortran namelist.
@end vtable

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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:

@findex gdb.print_options
@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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Here are the printers:

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

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

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

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

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

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

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

@smallexample
import gdb.printing

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

And here is the autoload support:

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

For example, if there are four frame filters:

@smallexample
Name         Priority

Filter1      5
Filter2      10
Filter3      100
Filter4      1
@end smallexample

The order that the frame filters will be called is:

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

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

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

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

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

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

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

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

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

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

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

Frame decorators have a mandatory interface, defined below.

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

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

@defun FrameDecorator.elided (self)

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

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

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

@defun FrameDecorator.function (self)

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

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

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

@defun FrameDecorator.address (self)

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

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

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

@defun FrameDecorator.filename (self)

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

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

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

@defun FrameDecorator.line (self):

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

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

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

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

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

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

A brief example:

@smallexample
class SymValueWrapper():

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

    def value(self):
        return self.val

    def symbol(self):
        return self.sym

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

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

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

        return args
@end smallexample
@end defun

@defun FrameDecorator.frame_locals (self)

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

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

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

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

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

        return vars
@end smallexample
@end defun

@defun FrameDecorator.inferior_frame (self):

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

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

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

@smallexample
import gdb

class FrameFilter():

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

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

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

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

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

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

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

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

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

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

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

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

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

@smallexample
class InlineFilter():

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

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

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

Below is the frame decorator for this example.

@smallexample
class InlinedFrameDecorator(FrameDecorator):

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

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

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

        return name
@end smallexample

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

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

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

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

@subheading Eliding Frames

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

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

This example comprises of three sections.

@smallexample
class InlineFrameFilter():

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

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

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

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

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

    def __iter__(self):
        return self

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

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

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

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

@smallexample
class ElidingInlineDecorator(FrameDecorator):

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

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

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

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

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

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

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

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

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

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

@subheading Unwinder Input

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

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

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

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

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

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

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

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

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

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

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

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

@end defun

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

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

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

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

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

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

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

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

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

@defun PendingFrame.language ()
Return the language of this frame, as a string, or None.
@end defun

@subheading Unwinder Output: UnwindInfo

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

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

@subheading The @code{gdb.unwinder} Module

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

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

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

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

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

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

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

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

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

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

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

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

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

@subheading Registering an Unwinder

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

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

@defun gdb.unwinder.register_unwinder (locus, unwinder, replace=False)
@var{locus} specifies to which unwinder list to prepend the
@var{unwinder}.  It can be either an object file (@pxref{Objfiles In
Python}), a program space (@pxref{Progspaces In Python}), or
@code{None}, in which case the unwinder is registered globally.  The
newly added @var{unwinder} will be called before any other unwinder
from the same locus.  Two unwinders in the same locus cannot have the
same name.  An attempt to add an unwinder with an already existing
name raises an exception unless @var{replace} is @code{True}, in which
case the old unwinder is deleted and the new unwinder is registered in
its place.

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

@subheading Unwinder Skeleton Code

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

@smallexample
from gdb.unwinder import Unwinder, FrameId

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

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

        # Create a FrameID.  Usually the frame is identified by a
        # stack pointer and the function address.
        sp = ... compute a stack address ...
        pc = ... compute function address ...
        unwind_info = pending_frame.create_unwind_info(FrameId(sp, pc))

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

        # Return the result:
        return unwind_info

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@table @code

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

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

@end table

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

private:
  int a_;
@};

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

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

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

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

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

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

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

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

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

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

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

@smallexample
MyClass obj(5);
@end smallexample

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

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

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

Consider another example with a C++ template class:

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

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

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

    def get_arg_types(self):
        return None

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

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

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

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

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

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

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

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

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

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

@anchor{gdbpy_inferior_connection}
@defvar Inferior.connection
The @code{gdb.TargetConnection} for this inferior (@pxref{Connections
In Python}), or @code{None} if this inferior has no connection.
@end defvar

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Here is an example:

@smallexample
def exit_handler (event):
    print ("event type: exit")
    if hasattr (event, 'exit_code'):
        print ("exit code: %d" % (event.exit_code))
    else:
        print ("exit code not available")

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

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

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

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

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

@table @code

@item events.cont
Emits @code{gdb.ContinueEvent}, which extends @code{gdb.ThreadEvent}.
This event indicates that the inferior has been continued after a
stop. For inherited attribute refer to @code{gdb.ThreadEvent} above.

@item events.exited
Emits @code{events.ExitedEvent}, which indicates that the inferior has
exited.  @code{events.ExitedEvent} has two attributes:

@defvar ExitedEvent.exit_code
An integer representing the exit code, if available, which the inferior 
has returned.  (The exit code could be unavailable if, for example,
@value{GDBN} detaches from the inferior.) If the exit code is unavailable,
the attribute does not exist.
@end defvar

@defvar ExitedEvent.inferior
A reference to the inferior which triggered the @code{exited} event.
@end defvar

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

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

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

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

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

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

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

@defvar BreakpointEvent.breakpoints
A sequence containing references to all the breakpoints (type 
@code{gdb.Breakpoint}) that were hit.
@xref{Breakpoints In Python}, for details of the @code{gdb.Breakpoint} object.
@end defvar

@defvar BreakpointEvent.breakpoint
A reference to the first breakpoint that was hit.  This attribute is
maintained for backward compatibility and is now deprecated in favor
of the @code{gdb.BreakpointEvent.breakpoints} attribute.
@end defvar

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

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

@item events.free_objfile
Emits @code{gdb.FreeObjFileEvent} which indicates that an object file
is about to be removed from @value{GDBN}.  One reason this can happen
is when the inferior calls @code{dlclose}.
@code{gdb.FreeObjFileEvent} has one attribute:

@defvar NewObjFileEvent.objfile
A reference to the object file (@code{gdb.Objfile}) which will be unloaded.
@xref{Objfiles In Python}, for details of the @code{gdb.Objfile} object.
@end defvar

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@item events.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:

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

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

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

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

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

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

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

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

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

@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 buffer with the raw instruction data.  In Python 3, the return value is a
@code{memoryview} object.
@end defvar

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if filename == current:
            continue

        rec.goto (i)
        return
@end smallexample

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

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

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

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

    return count
@end smallexample

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

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

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

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

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

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

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

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

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

A program space has the following methods:

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

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

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

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

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

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

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

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

@node Objfiles In Python
@subsubsection Objfiles In Python

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

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

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

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

@findex gdb.lookup_objfile
@defun gdb.lookup_objfile (name @r{[}, by_build_id@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:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@item gdb.FRAME_UNWIND_OUTERMOST
This frame is the outermost.

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

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

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

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

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

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

@end defun

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

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

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

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

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

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

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

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

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

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

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

@findex gdb.block_for_pc
@defun gdb.block_for_pc (pc)
Return the innermost @code{gdb.Block} containing the given @var{pc}
value.  If the block cannot be found for the @var{pc} value specified,
the function will return @code{None}.  This is identical to
@code{gdb.current_progspace().block_for_pc(pc)} and is included for
historical compatibility.
@end defun

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

@defun Block.is_valid ()
Returns @code{True} if the @code{gdb.Block} object is valid,
@code{False} if not.  A block object can become invalid if the block it
refers to doesn't exist anymore in the inferior.  All other
@code{gdb.Block} methods will throw an exception if it is invalid at
the time the method is called.  The block's validity is also checked
during iteration over symbols of the block.
@end defun

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

@defvar Block.start
The start address of the block.  This attribute is not writable.
@end defvar

@defvar Block.end
One past the last address that appears in the block.  This attribute
is not writable.
@end defvar

@defvar Block.function
The name of the block represented as a @code{gdb.Symbol}.  If the
block is not named, then this attribute holds @code{None}.  This
attribute is not writable.

For ordinary function blocks, the superblock is the static block.
However, you should note that it is possible for a function block to
have a superblock that is not the static block -- for instance this
happens for an inlined function.
@end defvar

@defvar Block.superblock
The block containing this block.  If this parent block does not exist,
this attribute holds @code{None}.  This attribute is not writable.
@end defvar

@defvar Block.global_block
The global block associated with this block.  This attribute is not
writable.
@end defvar

@defvar Block.static_block
The static block associated with this block.  This attribute is not
writable.
@end defvar

@defvar Block.is_global
@code{True} if the @code{gdb.Block} object is a global block,
@code{False} if not.  This attribute is not
writable.
@end defvar

@defvar Block.is_static
@code{True} if the @code{gdb.Block} object is a static block,
@code{False} if not.  This attribute is not writable.
@end defvar

@node Symbols In Python
@subsubsection Python representation of Symbols

@cindex symbols in python
@tindex gdb.Symbol

@value{GDBN} represents every variable, function and type as an
entry in a symbol table.  @xref{Symbols, ,Examining the Symbol Table}.
Similarly, Python represents these symbols in @value{GDBN} with the
@code{gdb.Symbol} object.

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

@findex gdb.lookup_symbol
@defun gdb.lookup_symbol (name @r{[}, block @r{[}, domain@r{]]})
This function searches for a symbol by name.  The search scope can be
restricted to the parameters defined in the optional domain and block
arguments.

@var{name} is the name of the symbol.  It must be a string.  The
optional @var{block} argument restricts the search to symbols visible
in that @var{block}.  The @var{block} argument must be a
@code{gdb.Block} object.  If omitted, the block for the current frame
is used.  The optional @var{domain} argument restricts
the search to the domain type.  The @var{domain} argument must be a
domain constant defined in the @code{gdb} module and described later
in this chapter.

The result is a tuple of two elements.
The first element is a @code{gdb.Symbol} object or @code{None} if the symbol
is not found.
If the symbol is found, the second element is @code{True} if the symbol
is a field of a method's object (e.g., @code{this} in C@t{++}),
otherwise it is @code{False}.
If the symbol is not found, the second element is @code{False}.
@end defun

@findex gdb.lookup_global_symbol
@defun gdb.lookup_global_symbol (name @r{[}, domain@r{]})
This function searches for a global symbol by name.
The search scope can be restricted to by the domain argument.

@var{name} is the name of the symbol.  It must be a string.
The optional @var{domain} argument restricts the search to the domain type.
The @var{domain} argument must be a domain constant defined in the @code{gdb}
module and described later in this chapter.

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

@findex gdb.lookup_static_symbol
@defun gdb.lookup_static_symbol (name @r{[}, domain@r{]})
This function searches for a global symbol with static linkage by name.
The search scope can be restricted to by the domain argument.

@var{name} is the name of the symbol.  It must be a string.
The optional @var{domain} argument restricts the search to the domain type.
The @var{domain} argument must be a domain constant defined in the @code{gdb}
module and described later in this chapter.

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

Note that this function will not find function-scoped static variables. To look
up such variables, iterate over the variables of the function's
@code{gdb.Block} and check that @code{block.addr_class} is
@code{gdb.SYMBOL_LOC_STATIC}.

There can be multiple global symbols with static linkage with the same
name.  This function will only return the first matching symbol that
it finds.  Which symbol is found depends on where @value{GDBN} is
currently stopped, as @value{GDBN} will first search for matching
symbols in the current object file, and then search all other object
files.  If the application is not yet running then @value{GDBN} will
search all object files in the order they appear in the debug
information.
@end defun

@findex gdb.lookup_static_symbols
@defun gdb.lookup_static_symbols (name @r{[}, domain@r{]})
Similar to @code{gdb.lookup_static_symbol}, this function searches for
global symbols with static linkage by name, and optionally restricted
by the domain argument.  However, this function returns a list of all
matching symbols found, not just the first one.

@var{name} is the name of the symbol.  It must be a string.
The optional @var{domain} argument restricts the search to the domain type.
The @var{domain} argument must be a domain constant defined in the @code{gdb}
module and described later in this chapter.

The result is a list of @code{gdb.Symbol} objects which could be empty
if no matching symbols were found.

Note that this function will not find function-scoped static variables. To look
up such variables, iterate over the variables of the function's
@code{gdb.Block} and check that @code{block.addr_class} is
@code{gdb.SYMBOL_LOC_STATIC}.
@end defun

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

@defvar Symbol.type
The type of the symbol or @code{None} if no type is recorded.
This attribute is represented as a @code{gdb.Type} object.
@xref{Types In Python}.  This attribute is not writable.
@end defvar

@defvar Symbol.symtab
The symbol table in which the symbol appears.  This attribute is
represented as a @code{gdb.Symtab} object.  @xref{Symbol Tables In
Python}.  This attribute is not writable.
@end defvar

@defvar Symbol.line
The line number in the source code at which the symbol was defined.
This is an integer.
@end defvar

@defvar Symbol.name
The name of the symbol as a string.  This attribute is not writable.
@end defvar

@defvar Symbol.linkage_name
The name of the symbol, as used by the linker (i.e., may be mangled).
This attribute is not writable.
@end defvar

@defvar Symbol.print_name
The name of the symbol in a form suitable for output.  This is either
@code{name} or @code{linkage_name}, depending on whether the user
asked @value{GDBN} to display demangled or mangled names.
@end defvar

@defvar Symbol.addr_class
The address class of the symbol.  This classifies how to find the value
of a symbol.  Each address class is a constant defined in the
@code{gdb} module and described later in this chapter.
@end defvar

@defvar Symbol.needs_frame
This is @code{True} if evaluating this symbol's value requires a frame
(@pxref{Frames In Python}) and @code{False} otherwise.  Typically,
local variables will require a frame, but other symbols will not.
@end defvar

@defvar Symbol.is_argument
@code{True} if the symbol is an argument of a function.
@end defvar

@defvar Symbol.is_constant
@code{True} if the symbol is a constant.
@end defvar

@defvar Symbol.is_function
@code{True} if the symbol is a function or a method.
@end defvar

@defvar Symbol.is_variable
@code{True} if the symbol is a variable.
@end defvar

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

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

@defun Symbol.value (@r{[}frame@r{]})
Compute the value of the symbol, as a @code{gdb.Value}.  For
functions, this computes the address of the function, cast to the
appropriate type.  If the symbol requires a frame in order to compute
its value, then @var{frame} must be given.  If @var{frame} is not
given, or if @var{frame} is invalid, then this method will throw an
exception.
@end defun

The available domain categories in @code{gdb.Symbol} are represented
as constants in the @code{gdb} module:

@vtable @code
@vindex SYMBOL_UNDEF_DOMAIN
@item gdb.SYMBOL_UNDEF_DOMAIN
This is used when a domain has not been discovered or none of the
following domains apply.  This usually indicates an error either
in the symbol information or in @value{GDBN}'s handling of symbols.

@vindex SYMBOL_VAR_DOMAIN
@item gdb.SYMBOL_VAR_DOMAIN
This domain contains variables, function names, typedef names and enum
type values.

@vindex SYMBOL_STRUCT_DOMAIN
@item gdb.SYMBOL_STRUCT_DOMAIN
This domain holds struct, union and enum type names.

@vindex SYMBOL_LABEL_DOMAIN
@item gdb.SYMBOL_LABEL_DOMAIN
This domain contains names of labels (for gotos).

@vindex SYMBOL_MODULE_DOMAIN
@item gdb.SYMBOL_MODULE_DOMAIN
This domain contains names of Fortran module types.

@vindex SYMBOL_COMMON_BLOCK_DOMAIN
@item gdb.SYMBOL_COMMON_BLOCK_DOMAIN
This domain contains names of Fortran common blocks.
@end vtable

The available address class categories in @code{gdb.Symbol} are represented
as constants in the @code{gdb} module:

@vtable @code
@vindex SYMBOL_LOC_UNDEF
@item gdb.SYMBOL_LOC_UNDEF
If this is returned by address class, it indicates an error either in
the symbol information or in @value{GDBN}'s handling of symbols.

@vindex SYMBOL_LOC_CONST
@item gdb.SYMBOL_LOC_CONST
Value is constant int.

@vindex SYMBOL_LOC_STATIC
@item gdb.SYMBOL_LOC_STATIC
Value is at a fixed address.

@vindex SYMBOL_LOC_REGISTER
@item gdb.SYMBOL_LOC_REGISTER
Value is in a register.

@vindex SYMBOL_LOC_ARG
@item gdb.SYMBOL_LOC_ARG
Value is an argument.  This value is at the offset stored within the
symbol inside the frame's argument list.

@vindex SYMBOL_LOC_REF_ARG
@item gdb.SYMBOL_LOC_REF_ARG
Value address is stored in the frame's argument list.  Just like
@code{LOC_ARG} except that the value's address is stored at the
offset, not the value itself.

@vindex SYMBOL_LOC_REGPARM_ADDR
@item gdb.SYMBOL_LOC_REGPARM_ADDR
Value is a specified register.  Just like @code{LOC_REGISTER} except
the register holds the address of the argument instead of the argument
itself.

@vindex SYMBOL_LOC_LOCAL
@item gdb.SYMBOL_LOC_LOCAL
Value is a local variable.

@vindex SYMBOL_LOC_TYPEDEF
@item gdb.SYMBOL_LOC_TYPEDEF
Value not used.  Symbols in the domain @code{SYMBOL_STRUCT_DOMAIN} all
have this class.

@vindex SYMBOL_LOC_LABEL
@item gdb.SYMBOL_LOC_LABEL
Value is a label.

@vindex SYMBOL_LOC_BLOCK
@item gdb.SYMBOL_LOC_BLOCK
Value is a block.

@vindex SYMBOL_LOC_CONST_BYTES
@item gdb.SYMBOL_LOC_CONST_BYTES
Value is a byte-sequence.

@vindex SYMBOL_LOC_UNRESOLVED
@item gdb.SYMBOL_LOC_UNRESOLVED
Value is at a fixed address, but the address of the variable has to be
determined from the minimal symbol table whenever the variable is
referenced.

@vindex SYMBOL_LOC_OPTIMIZED_OUT
@item gdb.SYMBOL_LOC_OPTIMIZED_OUT
The value does not actually exist in the program.

@vindex SYMBOL_LOC_COMPUTED
@item gdb.SYMBOL_LOC_COMPUTED
The value's address is a computed location.

@vindex SYMBOL_LOC_COMMON_BLOCK
@item gdb.SYMBOL_LOC_COMMON_BLOCK
The value's address is a symbol.  This is only used for Fortran common
blocks.
@end vtable

@node Symbol Tables In Python
@subsubsection Symbol table representation in Python

@cindex symbol tables in python
@tindex gdb.Symtab
@tindex gdb.Symtab_and_line

Access to symbol table data maintained by @value{GDBN} on the inferior
is exposed to Python via two objects: @code{gdb.Symtab_and_line} and
@code{gdb.Symtab}.  Symbol table and line data for a frame is returned
from the @code{find_sal} method in @code{gdb.Frame} object.
@xref{Frames In Python}.

For more information on @value{GDBN}'s symbol table management, see
@ref{Symbols, ,Examining the Symbol Table}, for more information.

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

@defvar Symtab_and_line.symtab
The symbol table object (@code{gdb.Symtab}) for this frame.
This attribute is not writable.
@end defvar

@defvar Symtab_and_line.pc
Indicates the start of the address range occupied by code for the
current source line.  This attribute is not writable.
@end defvar

@defvar Symtab_and_line.last
Indicates the end of the address range occupied by code for the current
source line.  This attribute is not writable.
@end defvar

@defvar Symtab_and_line.line
Indicates the current line number for this object.  This
attribute is not writable.
@end defvar

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

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

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

@defvar Symtab.filename
The symbol table's source filename.  This attribute is not writable.
@end defvar

@defvar Symtab.objfile
The symbol table's backing object file.  @xref{Objfiles In Python}.
This attribute is not writable.
@end defvar

@defvar Symtab.producer
The name and possibly version number of the program that
compiled the code in the symbol table.
The contents of this string is up to the compiler.
If no producer information is available then @code{None} is returned.
This attribute is not writable.
@end defvar

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

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

@defun Symtab.fullname ()
Return the symbol table's source absolute file name.
@end defun

@defun Symtab.global_block ()
Return the global block of the underlying symbol table.
@xref{Blocks In Python}.
@end defun

@defun Symtab.static_block ()
Return the static block of the underlying symbol table.
@xref{Blocks In Python}.
@end defun

@defun Symtab.linetable ()
Return the line table associated with the symbol table.
@xref{Line Tables In Python}.
@end defun

@node Line Tables In Python
@subsubsection Manipulating line tables using Python

@cindex line tables in python
@tindex gdb.LineTable

Python code can request and inspect line table information from a
symbol table that is loaded in @value{GDBN}.  A line table is a
mapping of source lines to their executable locations in memory.  To
acquire the line table information for a particular symbol table, use
the @code{linetable} function (@pxref{Symbol Tables In Python}).

A @code{gdb.LineTable} is iterable.  The iterator returns
@code{LineTableEntry} objects that correspond to the source line and
address for each line table entry.  @code{LineTableEntry} objects have
the following attributes:

@defvar LineTableEntry.line
The source line number for this line table entry.  This number
corresponds to the actual line of source.  This attribute is not
writable.
@end defvar

@defvar LineTableEntry.pc
The address that is associated with the line table entry where the
executable code for that source line resides in memory.  This
attribute is not writable.
@end defvar

As there can be multiple addresses for a single source line, you may
receive multiple @code{LineTableEntry} objects with matching
@code{line} attributes, but with different @code{pc} attributes.  The
iterator is sorted in ascending @code{pc} order.  Here is a small
example illustrating iterating over a line table.

@smallexample
symtab = gdb.selected_frame().find_sal().symtab
linetable = symtab.linetable()
for line in linetable:
   print ("Line: "+str(line.line)+" Address: "+hex(line.pc))
@end smallexample

This will have the following output:

@smallexample
Line: 33 Address: 0x4005c8L
Line: 37 Address: 0x4005caL
Line: 39 Address: 0x4005d2L
Line: 40 Address: 0x4005f8L
Line: 42 Address: 0x4005ffL
Line: 44 Address: 0x400608L
Line: 42 Address: 0x40060cL
Line: 45 Address: 0x400615L
@end smallexample

In addition to being able to iterate over a @code{LineTable}, it also
has the following direct access methods:

@defun LineTable.line (line)
Return a Python @code{Tuple} of @code{LineTableEntry} objects for any
entries in the line table for the given @var{line}, which specifies
the source code line.  If there are no entries for that source code
@var{line}, the Python @code{None} is returned.
@end defun

@defun LineTable.has_line (line)
Return a Python @code{Boolean} indicating whether there is an entry in
the line table for this source line.  Return @code{True} if an entry
is found, or @code{False} if not.
@end defun

@defun LineTable.source_lines ()
Return a Python @code{List} of the source line numbers in the symbol
table.  Only lines with executable code locations are returned.  The
contents of the @code{List} will just be the source line entries
represented as Python @code{Long} values.
@end defun

@node Breakpoints In Python
@subsubsection Manipulating breakpoints using Python

@cindex breakpoints in python
@tindex gdb.Breakpoint

Python code can manipulate breakpoints via the @code{gdb.Breakpoint}
class.

A breakpoint can be created using one of the two forms of the
@code{gdb.Breakpoint} constructor.  The first one accepts a string
like one would pass to the @code{break}
(@pxref{Set Breaks,,Setting Breakpoints}) and @code{watch}
(@pxref{Set Watchpoints, , Setting Watchpoints}) commands, and can be used to
create both breakpoints and watchpoints.  The second accepts separate Python
arguments similar to @ref{Explicit Locations}, and can only be used to create
breakpoints.

@defun Breakpoint.__init__ (spec @r{[}, type @r{][}, wp_class @r{][}, internal @r{][}, temporary @r{][}, qualified @r{]})
Create a new breakpoint according to @var{spec}, which is a string naming the
location of a breakpoint, or an expression that defines a watchpoint.  The
string should describe a location in a format recognized by the @code{break}
command (@pxref{Set Breaks,,Setting Breakpoints}) or, in the case of a
watchpoint, by the @code{watch} command
(@pxref{Set Watchpoints, , Setting Watchpoints}).

The optional @var{type} argument specifies the type of the breakpoint to create,
as defined below.

The optional @var{wp_class} argument defines the class of watchpoint to create,
if @var{type} is @code{gdb.BP_WATCHPOINT}.  If @var{wp_class} is omitted, it
defaults to @code{gdb.WP_WRITE}.

The optional @var{internal} argument allows the breakpoint to become invisible
to the user.  The breakpoint will neither be reported when created, nor will it
be listed in the output from @code{info breakpoints} (but will be listed with
the @code{maint info breakpoints} command).

The optional @var{temporary} argument makes the breakpoint a temporary
breakpoint.  Temporary breakpoints are deleted after they have been hit.  Any
further access to the Python breakpoint after it has been hit will result in a
runtime error (as that breakpoint has now been automatically deleted).

The optional @var{qualified} argument is a boolean that allows interpreting
the function passed in @code{spec} as a fully-qualified name.  It is equivalent
to @code{break}'s @code{-qualified} flag (@pxref{Linespec Locations} and
@ref{Explicit Locations}).

@end defun

@defun Breakpoint.__init__ (@r{[} source @r{][}, function @r{][}, label @r{][}, line @r{]}, @r{][} internal @r{][}, temporary @r{][}, qualified @r{]})
This second form of creating a new breakpoint specifies the explicit
location (@pxref{Explicit Locations}) using keywords.  The new breakpoint will
be created in the specified source file @var{source}, at the specified
@var{function}, @var{label} and @var{line}.

@var{internal}, @var{temporary} and @var{qualified} have the same usage as
explained previously.
@end defun

The available types are represented by constants defined in the @code{gdb}
module:

@vtable @code
@vindex BP_BREAKPOINT
@item gdb.BP_BREAKPOINT
Normal code breakpoint.

@vindex BP_HARDWARE_BREAKPOINT
@item gdb.BP_HARDWARE_BREAKPOINT
Hardware assisted code breakpoint.

@vindex BP_WATCHPOINT
@item gdb.BP_WATCHPOINT
Watchpoint breakpoint.

@vindex BP_HARDWARE_WATCHPOINT
@item gdb.BP_HARDWARE_WATCHPOINT
Hardware assisted watchpoint.

@vindex BP_READ_WATCHPOINT
@item gdb.BP_READ_WATCHPOINT
Hardware assisted read watchpoint.

@vindex BP_ACCESS_WATCHPOINT
@item gdb.BP_ACCESS_WATCHPOINT
Hardware assisted access watchpoint.

@vindex BP_CATCHPOINT
@item gdb.BP_CATCHPOINT
Catchpoint.  Currently, this type can't be used when creating
@code{gdb.Breakpoint} objects, but will be present in
@code{gdb.Breakpoint} objects reported from
@code{gdb.BreakpointEvent}s (@pxref{Events In Python}).
@end vtable

The available watchpoint types are represented by constants defined in the
@code{gdb} module:

@vtable @code
@vindex WP_READ
@item gdb.WP_READ
Read only watchpoint.

@vindex WP_WRITE
@item gdb.WP_WRITE
Write only watchpoint.

@vindex WP_ACCESS
@item gdb.WP_ACCESS
Read/Write watchpoint.
@end vtable

@defun Breakpoint.stop (self)
The @code{gdb.Breakpoint} class can be sub-classed and, in
particular, you may choose to implement the @code{stop} method.
If this method is defined in a sub-class of @code{gdb.Breakpoint},
it will be called when the inferior reaches any location of a
breakpoint which instantiates that sub-class.  If the method returns
@code{True}, the inferior will be stopped at the location of the
breakpoint, otherwise the inferior will continue.

If there are multiple breakpoints at the same location with a
@code{stop} method, each one will be called regardless of the
return status of the previous.  This ensures that all @code{stop}
methods have a chance to execute at that location.  In this scenario
if one of the methods returns @code{True} but the others return
@code{False}, the inferior will still be stopped.

You should not alter the execution state of the inferior (i.e.@:, step,
next, etc.), alter the current frame context (i.e.@:, change the current
active frame), or alter, add or delete any breakpoint.  As a general
rule, you should not alter any data within @value{GDBN} or the inferior
at this time.

Example @code{stop} implementation:

@smallexample
class MyBreakpoint (gdb.Breakpoint):
      def stop (self):
        inf_val = gdb.parse_and_eval("foo")
        if inf_val == 3:
          return True
        return False
@end smallexample
@end defun

@defun Breakpoint.is_valid ()
Return @code{True} if this @code{Breakpoint} object is valid,
@code{False} otherwise.  A @code{Breakpoint} object can become invalid
if the user deletes the breakpoint.  In this case, the object still
exists, but the underlying breakpoint does not.  In the cases of
watchpoint scope, the watchpoint remains valid even if execution of the
inferior leaves the scope of that watchpoint.
@end defun

@defun Breakpoint.delete ()
Permanently deletes the @value{GDBN} breakpoint.  This also
invalidates the Python @code{Breakpoint} object.  Any further access
to this object's attributes or methods will raise an error.
@end defun

@defvar Breakpoint.enabled
This attribute is @code{True} if the breakpoint is enabled, and
@code{False} otherwise.  This attribute is writable.  You can use it to enable
or disable the breakpoint.
@end defvar

@defvar Breakpoint.silent
This attribute is @code{True} if the breakpoint is silent, and
@code{False} otherwise.  This attribute is writable.

Note that a breakpoint can also be silent if it has commands and the
first command is @code{silent}.  This is not reported by the
@code{silent} attribute.
@end defvar

@defvar Breakpoint.pending
This attribute is @code{True} if the breakpoint is pending, and
@code{False} otherwise.  @xref{Set Breaks}.  This attribute is
read-only.
@end defvar

@anchor{python_breakpoint_thread}
@defvar Breakpoint.thread
If the breakpoint is thread-specific, this attribute holds the
thread's global id.  If the breakpoint is not thread-specific, this
attribute is @code{None}.  This attribute is writable.
@end defvar

@defvar Breakpoint.task
If the breakpoint is Ada task-specific, this attribute holds the Ada task
id.  If the breakpoint is not task-specific (or the underlying
language is not Ada), this attribute is @code{None}.  This attribute
is writable.
@end defvar

@defvar Breakpoint.ignore_count
This attribute holds the ignore count for the breakpoint, an integer.
This attribute is writable.
@end defvar

@defvar Breakpoint.number
This attribute holds the breakpoint's number --- the identifier used by
the user to manipulate the breakpoint.  This attribute is not writable.
@end defvar

@defvar Breakpoint.type
This attribute holds the breakpoint's type --- the identifier used to
determine the actual breakpoint type or use-case.  This attribute is not
writable.
@end defvar

@defvar Breakpoint.visible
This attribute tells whether the breakpoint is visible to the user
when set, or when the @samp{info breakpoints} command is run.  This
attribute is not writable.
@end defvar

@defvar Breakpoint.temporary
This attribute indicates whether the breakpoint was created as a
temporary breakpoint.  Temporary breakpoints are automatically deleted
after that breakpoint has been hit.  Access to this attribute, and all
other attributes and functions other than the @code{is_valid}
function, will result in an error after the breakpoint has been hit
(as it has been automatically deleted).  This attribute is not
writable.
@end defvar

@defvar Breakpoint.hit_count
This attribute holds the hit count for the breakpoint, an integer.
This attribute is writable, but currently it can only be set to zero.
@end defvar

@defvar Breakpoint.location
This attribute holds the location of the breakpoint, as specified by
the user.  It is a string.  If the breakpoint does not have a location
(that is, it is a watchpoint) the attribute's value is @code{None}.  This
attribute is not writable.
@end defvar

@defvar Breakpoint.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

@findex Architecture.integer_type
@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.  For Python 3 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

In Python 2 @code{bytes} and @code{str} are aliases, so the result is
already a string, if the response includes non-printable characters,
or null characters, then these will be present in the result, care
should be taken when processing the result to handle this case.

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.

@findex gdb.register_window_type
@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
