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

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

You can extend @value{GDBN} using the @uref{http://www.python.org/,
Python programming language}.  This feature is available only if
@value{GDBN} was configured using @option{--with-python}.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

By default this option is set to @samp{auto}.  In this mode, provided
the @code{python ignore-environment} setting is @samp{off}, the
environment variable @env{PYTHONDONTWRITEBYTECODE} is examined to see
if it should write out byte-code or not.
@env{PYTHONDONTWRITEBYTECODE} is considered to be off/disabled either
when set to the empty string or when the environment variable doesn't
exist.  All other settings, including those which don't seem to make
sense, indicate that it's on/enabled.

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

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

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

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

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

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

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

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

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

@menu
* Basic Python::                Basic Python Functions.
* Threading in GDB::		Using Python threads in GDB.
* Exception Handling::          How Python exceptions are translated.
* Values From Inferior::        Python representation of values.
* Types In Python::             Python representation of types.
* Pretty Printing API::         Pretty-printing values.
* Selecting Pretty-Printers::   How GDB chooses a pretty-printer.
* Writing a Pretty-Printer::    Writing a Pretty-Printer.
* Type Printing API::           Pretty-printing types.
* Frame Filter API::            Filtering Frames.
* Frame Decorator API::         Decorating Frames.
* Writing a Frame Filter::      Writing a Frame Filter.
* Unwinding Frames in Python::  Writing frame unwinder.
* Xmethods In Python::          Adding and replacing methods of C++ classes.
* Xmethod API::                 Xmethod types.
* Writing an Xmethod::          Writing an xmethod.
* Inferiors In Python::         Python representation of inferiors (processes)
* Events In Python::            Listening for events from @value{GDBN}.
* Threads In Python::           Accessing inferior threads from Python.
* Recordings In Python::        Accessing recordings from Python.
* CLI Commands In Python::      Implementing new CLI commands in Python.
* GDB/MI Commands In Python::   Implementing new @sc{gdb/mi} commands in Python.
* GDB/MI Notifications In Python:: Implementing new @sc{gdb/mi} notifications 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
* Missing Debug Info In Python:: Handle missing debug info from Python.
@end menu

@node Basic Python
@subsubsection Basic Python

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

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

@itemize @bullet
@item
@value{GDBN} installs handlers for @code{SIGCHLD} and @code{SIGINT}.
Python code must not override these, or even change the options using
@code{sigaction}.  If your program changes the handling of these
signals, @value{GDBN} will most likely stop working correctly.  Note
that it is unfortunately common for GUI toolkits to install a
@code{SIGCHLD} handler.  When creating a new Python thread, you can
use @code{gdb.block_signals} or @code{gdb.Thread} to handle this
correctly; see @ref{Threading in GDB}.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@end table

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

Here are some examples of the possible string formats:

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

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

@node Threading in GDB
@subsubsection Threading in GDB

@value{GDBN} is not thread-safe.  If your Python program uses multiple
threads, you must be careful to only call @value{GDBN}-specific
functions in the @value{GDBN} thread.  @value{GDBN} provides some
functions to help with this.

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

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

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

@defun gdb.interrupt ()
This causes @value{GDBN} to react as if the user had typed a control-C
character at the terminal.  That is, if the inferior is running, it is
interrupted; if a @value{GDBN} command is executing, it is stopped;
and if a Python command is running, @code{KeyboardInterrupt} will be
raised.

Unlike most Python APIs in @value{GDBN}, @code{interrupt} is
thread-safe.
@end defun

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

Unlike most Python APIs in @value{GDBN}, @code{post_event} is
thread-safe.  For example:

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


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

When executing the @code{python} command, Python exceptions
uncaught within the Python code are translated to calls to
@value{GDBN} error-reporting mechanism.  If the command that called
@code{python} does not handle the error, @value{GDBN} will
terminate it and print an error message.  Exactly what will be printed
depends on @code{set python print-stack} (@pxref{Python Commands}).
Example:

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

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

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

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

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

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

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


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

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

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

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

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

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

@smallexample
bar = some_val + 2
@end smallexample

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

@smallexample
val3 = val1 + val2
@end smallexample

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

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

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

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

@smallexample
bar = some_val[foo_field]
@end smallexample

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

@smallexample
result = some_array[23]
@end smallexample

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

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

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

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

The following attributes are provided:

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

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

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

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

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

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

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

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

@defvar Value.bytes
The value of this attribute is a @code{bytes} object containing the
bytes that make up this @code{Value}'s complete value in little endian
order.  If the complete contents of this value are not available then
accessing this attribute will raise an exception.

This attribute can also be assigned to.  The new value should be a
buffer object (e.g.@: a @code{bytes} object), the length of the new
buffer must exactly match the length of this @code{Value}'s type.  The
bytes values in the new buffer should be in little endian order.

As with @code{Value.assign} (@pxref{Value.assign}), if this value
cannot be assigned to, then an exception will be thrown.
@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

@anchor{Value.assign}
@defun Value.assign (rhs)
Assign @var{rhs} to this value, and return @code{None}.  If this value
cannot be assigned to, or if the assignment is invalid for some reason
(for example a type-checking failure), an exception will be thrown.
@end defun

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

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

@smallexample
int *foo;
@end smallexample

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@defun Value.to_array ()
If this value is array-like (@pxref{Type.is_array_like}), then this
method converts it to an array, which is returned.  If this value is
already an array, it is simply returned.  Otherwise, an exception is
throw.
@end defun

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

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

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

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

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

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

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

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

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

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

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

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

This method does not return a value.
@end defun


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@defvar Type.is_string_like
A boolean indicating whether this type is string-like.  Like
@code{Type.is_array_like}, this is determined based on the originating
language of the type.
@end defvar

The following methods are provided:

@defun Type.fields ()

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

@itemize @bullet

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

@item
Enum types have one field per enum constant.

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

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

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

@end itemize

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Because @value{GDBN} did not document extensibility for
pretty-printers, by default @value{GDBN} will assume that only the
basic pretty-printer methods may be available.  The basic methods are
marked as such, below.

To allow extensibility, @value{GDBN} provides the
@code{gdb.ValuePrinter} base class.  This class does not provide any
attributes or behavior, but instead serves as a tag that can be
recognized by @value{GDBN}.  For such printers, @value{GDBN} reserves
all attributes starting with a lower-case letter.  That is, in the
future, @value{GDBN} may add a new method or attribute to the
pretty-printer protocol, and @code{gdb.ValuePrinter}-based printers
are expected to handle this gracefully.  A simple way to do this would
be to use a leading underscore (or two, following the Python
name-mangling scheme) to any attributes local to the implementation.

@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 is a basic method, and 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 is a basic method, and 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.

This is a basic method, and is optional.

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 performed in this method and nothing is printed.

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

@defun pretty_printer.num_children ()
This is not a basic method, so @value{GDBN} will only ever call it for
objects derived from @code{gdb.ValuePrinter}.

If available, this method should return the number of children.
@code{None} may be returned if the number can't readily be computed.
@end defun

@defun pretty_printer.child (n)
This is not a basic method, so @value{GDBN} will only ever call it for
objects derived from @code{gdb.ValuePrinter}.

If available, this method should return the child value indicated by
@var{n}.  Indices start at zero.
@end defun

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

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

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

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

@smallexample
(gdb) python print (gdb.print_options ()['max_elements'])
200
@end smallexample
@end defun

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

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

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

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

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

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

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

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

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

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

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

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

Here is an example showing how a @code{std::string} printer might be
written.  @xref{Pretty Printing API}, for details on the API this class
must provide.  Note that this example uses the @code{gdb.ValuePrinter}
base class, and is careful to use a leading underscore for its local
state.

@smallexample
class StdStringPrinter(gdb.ValuePrinter):
    "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(gdb.ValuePrinter):
    """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(gdb.ValuePrinter):
    """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}
maintains 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 well-hardened yet).  For example, making an inferior call from
an unwinder is unadvisable, as an inferior call will reset
@value{GDBN}'s stack unwinding process, potentially causing re-entrant
unwinding.

@subheading Unwinder Input

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

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

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

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

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

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

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

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

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

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

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

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

@end defun

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

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

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

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

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

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

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

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

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

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

@subheading Unwinder Output: UnwindInfo

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

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

@subheading The @code{gdb.unwinder} Module

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

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

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

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

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

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

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

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

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

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

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

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

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

@subheading Registering an Unwinder

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

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

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

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

@subheading Unwinder Skeleton Code

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

@smallexample
from gdb.unwinder import Unwinder, FrameId

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

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

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

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

        # Return the result:
        return unwind_info

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@table @code

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

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

@end table

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

private:
  int a_;
@};

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

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

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

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

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

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

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

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

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

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

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

@smallexample
MyClass obj(5);
@end smallexample

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

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

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

Consider another example with a C++ template class:

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

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

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

    def get_arg_types(self):
        return None

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

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

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

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

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

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

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

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

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

@defvar Inferior.num
ID of inferior, as assigned by @value{GDBN}.  You can use this to make
Python breakpoints inferior-specific, for example
(@pxref{python_breakpoint_inferior,,The Breakpoint.inferior
attribute}).
@end defvar

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

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

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

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

@defvar Inferior.main_name
A string holding the name of this inferior's ``main'' function, if it
can be determined.  If the name of main is not known, this is
@code{None}.
@end defvar

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

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

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

Either a string or a sequence of strings can be assigned to this
attribute.  When a string is assigned, it is assumed to have any
necessary quoting for the shell; when a sequence is assigned, the
quoting is applied by @value{GDBN}.
@end defvar

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

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

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

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

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

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

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

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

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


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

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

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

@defun Inferior.unset_env (name)
Unset the environment variable @var{name}.  @var{name} must be a
string.
@end defun

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

@anchor{choosing attribute names}
When selecting a name for a new attribute, avoid starting the new
attribute name with a lower case letter; future attributes added by
@value{GDBN} will start with a lower case letter.  Additionally, avoid
starting attribute names with two underscore characters, as these
could clash with Python builtin attribute names.

In this contrived example we record the time when an inferior last
stopped:

@smallexample
@group
(@value{GDBP}) python
import datetime

def thread_stopped(event):
    if event.inferior_thread is not None:
        thread = event.inferior_thread
    else:
        thread = gdb.selected_thread()
    inferior = thread.inferior
    inferior._last_stop_time = datetime.datetime.today()

gdb.events.stop.connect(thread_stopped)
@end group
@group
(@value{GDBP}) file /tmp/hello
Reading symbols from /tmp/hello...
(@value{GDBP}) start
Temporary breakpoint 1 at 0x401198: file /tmp/hello.c, line 18.
Starting program: /tmp/hello

Temporary breakpoint 1, main () at /tmp/hello.c:18
18	  printf ("Hello World\n");
(@value{GDBP}) python print(gdb.selected_inferior()._last_stop_time)
2024-01-04 14:48:41.347036
@end group
@end smallexample

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

@code{gdb.StopEvent} has the following additional attributes:

@defvar StopEvent.details
A dictionary holding any details relevant to the stop.  The exact keys
and values depend on the type of stop, but are identical to the
corresponding MI output (@pxref{GDB/MI Async Records}).

A dictionary was used for this (rather than adding attributes directly
to the event object) so that the MI keys could be used unchanged.
@end defvar

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@defvar ConnectionEvent.connection
The @code{gdb.TargetConnection} that is being removed.
@end defvar

@item events.executable_changed
Emits @code{gdb.ExecutableChangedEvent} which indicates that the
@code{gdb.Progspace.executable_filename} has changed.

This event is emitted when either the value of
@code{gdb.Progspace.executable_filename } has changed to name a
different file, or the executable file named by
@code{gdb.Progspace.executable_filename} has changed on disk, and
@value{GDBN} has therefore reloaded it.

@defvar ExecutableChangedEvent.progspace
The @code{gdb.Progspace} in which the current executable has changed.
The file name of the updated executable will be visible in
@code{gdb.Progspace.executable_filename} (@pxref{Progspaces In Python}).
@end defvar
@defvar ExecutableChangedEvent.reload
This attribute will be @code{True} if the value of
@code{gdb.Progspace.executable_filename} didn't change, but the file
it names changed on disk instead, and @value{GDBN} reloaded it.

When this attribute is @code{False}, the value in
@code{gdb.Progspace.executable_filename} was changed to name a
different file.
@end defvar

Remember that @value{GDBN} tracks the executable file and the symbol
file separately, these are visible as
@code{gdb.Progspace.executable_filename} and
@code{gdb.Progspace.filename} respectively.  When using the @kbd{file}
command, @value{GDBN} updates both of these fields, but the executable
file is updated first, so when this event is emitted, the executable
filename will have changed, but the symbol filename might still hold
its previous value.

@item events.new_progspace
This is emitted when @value{GDBN} adds a new program space
(@pxref{Progspaces In Python,,Program Spaces In Python}).  The event
is of type @code{gdb.NewProgspaceEvent}, and has a single read-only
attribute:

@defvar NewProgspaceEvent.progspace
The @code{gdb.Progspace} that was added to @value{GDBN}.
@end defvar

No @code{NewProgspaceEvent} is emitted for the very first program
space, which is assigned to the first inferior.  This first program
space is created within @value{GDBN} before any Python scripts are
sourced.

@item events.free_progspace
This is emitted when @value{GDBN} removes a program space
(@pxref{Progspaces In Python,,Program Spaces In Python}), for example
as a result of the @kbd{remove-inferiors} command
(@pxref{remove_inferiors_cli,,@kbd{remove-inferiors}}).  The event is
of type @code{gdb.FreeProgspaceEvent}, and has a single read-only
attribute:

@defvar FreeProgspaceEvent.progspace
The @code{gdb.Progspace} that is about to be removed from
@value{GDBN}.
@end defvar

@end table

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

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

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

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

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

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

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

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

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

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

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

@defvar InferiorThread.ptid_string
This read-only attribute contains a string representing
@code{InferiorThread.ptid}.  This is the string that @value{GDBN} uses
in the @samp{Target Id} column in the @kbd{info threads} output
(@pxref{info_threads,,@samp{info threads}}).
@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

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

@xref{choosing attribute names}, for guidance on selecting a suitable
name for new attributes.

In this contrived example we record the time when a thread last
stopped:

@smallexample
@group
(@value{GDBP}) python
import datetime

def thread_stopped(event):
    if event.inferior_thread is not None:
        thread = event.inferior_thread
    else:
        thread = gdb.selected_thread()
    thread._last_stop_time = datetime.datetime.today()

gdb.events.stop.connect(thread_stopped)
@end group
@group
(@value{GDBP}) file /tmp/hello
Reading symbols from /tmp/hello...
(@value{GDBP}) start
Temporary breakpoint 1 at 0x401198: file /tmp/hello.c, line 18.
Starting program: /tmp/hello

Temporary breakpoint 1, main () at /tmp/hello.c:18
18	  printf ("Hello World\n");
(@value{GDBP}) python print(gdb.selected_thread()._last_stop_time)
2024-01-04 14:48:41.347036
@end group
@end smallexample

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@defvar Instruction.data
A @code{memoryview} object holding the raw instruction data.
@end defvar

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        if filename == current:
            continue

        rec.goto (i)
        return
@end smallexample

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

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

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

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

    return count
@end smallexample

@node CLI Commands In Python
@subsubsection CLI Commands In Python

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

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

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

There is no support for multi-line commands.

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

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

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

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

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

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

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

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

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

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

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

@end defun

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

HelloWorld ()
@end smallexample

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

@node GDB/MI Commands In Python
@subsubsection @sc{gdb/mi} Commands In Python

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

@defun MICommand.__init__ (name)
The object initializer for @code{MICommand} registers the new command
with @value{GDBN}.  This initializer is normally invoked from the
subclass' own @code{__init__} method.

@var{name} is the name of the command.  It must be a valid name of a
@sc{gdb/mi} command, and in particular must start with a hyphen
(@code{-}).  Reusing the name of a built-in @sc{gdb/mi} is not
allowed, and a @code{RuntimeError} will be raised.  Using the name
of an @sc{gdb/mi} command previously defined in Python is allowed, the
previous command will be replaced with the new command.
@end defun

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

@node GDB/MI Notifications In Python
@subsubsection @sc{gdb/mi} Notifications In Python

@cindex MI notifications in python
@cindex notifications in python, GDB/MI
@cindex python notifications, GDB/MI

It is possible to emit @sc{gdb/mi} notifications from
Python.  Use the @code{gdb.notify_mi} function to do that.

@defun gdb.notify_mi (name @r{[}, data@r{]})
Emit a @sc{gdb/mi} asynchronous notification.  @var{name} is the name of the
notification, consisting of alphanumeric characters and a hyphen (@code{-}).
@var{data} is any additional data to be emitted with the notification, passed
as a Python dictionary. This argument is optional. The dictionary is converted
to a @sc{gdb/mi} @var{result} records (@pxref{GDB/MI Output Syntax}) the same way
as result of Python MI command (@pxref{GDB/MI Commands In Python}).

If @var{data} is @code{None} then no additional values are emitted.
@end defun

While using existing notification names (@pxref{GDB/MI Async Records}) with
@code{gdb.notify_mi} is allowed, users are encouraged to prefix user-defined
notification with a hyphen (@code{-}) to avoid possible conflict.
@value{GDBN} will never introduce notification starting with hyphen.

Here is how to emit @code{=-connection-removed} whenever a connection to remote
GDB server is closed (@pxref{Connections In Python}):

@smallexample
def notify_connection_removed(event):
    data = @{"id": event.connection.num, "type": event.connection.type@}
    gdb.notify_mi("-connection-removed", data)


gdb.events.connection_removed.connect(notify_connection_removed)
@end smallexample

Then, each time a connection is closed, there will be a notification on MI channel:

@smallexample
=-connection-removed,id="1",type="remote"
@end smallexample

@node Parameters In Python
@subsubsection Parameters In Python

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

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

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

@defun Parameter.__init__ (name, command_class, parameter_class @r{[}, enum_sequence@r{]})
The object initializer for @code{Parameter} registers the new
parameter with @value{GDBN}.  This initializer is normally invoked
from the subclass' own @code{__init__} method.

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

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

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

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

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

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

The help text for the new parameter includes the Python documentation
string from the parameter's class, if there is one.  If there is no
documentation string, a default value is used.  The documentation
string is included in the output of the parameters @code{help set} and
@code{help show} commands, and should be written taking this into
account.
@end defun

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

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

The @code{set_doc} value is examined when @code{Parameter.__init__} is
invoked; subsequent changes have no effect.
@end defvar

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

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

The @code{show_doc} value is examined when @code{Parameter.__init__}
is invoked; subsequent changes have no effect.
@end defvar

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@findex PARAM_ZINTEGER
@findex gdb.PARAM_ZINTEGER
@item gdb.PARAM_ZINTEGER
The value is a signed integer.  This is like @code{PARAM_INTEGER},
except that 0 is allowed and the value of @code{None} is not supported.

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

@findex PARAM_ZUINTEGER_UNLIMITED
@findex gdb.PARAM_ZUINTEGER_UNLIMITED
@item gdb.PARAM_ZUINTEGER_UNLIMITED
The value is a signed integer.  This is like @code{PARAM_INTEGER}
including that the value of @code{None} should be interpreted to mean
``unlimited'' (literal @code{'unlimited'} can also be used to set that
value), except that 0 is allowed, and the value cannot be negative,
except the special value -1 is returned for the setting of ``unlimited''.

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

@node Functions In Python
@subsubsection Writing new convenience functions

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

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

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

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

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

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

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

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

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

Greet ()
@end smallexample

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

Now you can use the function in an expression:

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

@node Progspaces In Python
@subsubsection Program Spaces In Python

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

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

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

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

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

@defvar Progspace.filename
The file name, as a string, of the main symbol file (from which debug
symbols have been loaded) for the progspace, e.g.@: the argument to
the @kbd{symbol-file} or @kbd{file} commands.

If there is no main symbol table currently loaded, then this attribute
will be @code{None}.
@end defvar

@defvar Progspace.symbol_file
The @code{gdb.Objfile} representing the main symbol file (from which
debug symbols have been loaded) for the @code{gdb.Progspace}.  This is
the symbol file set by the @kbd{symbol-file} or @kbd{file} commands.

This will be the @code{gdb.Objfile} representing
@code{Progspace.filename} when @code{Progspace.filename} is not
@code{None}.

If there is no main symbol table currently loaded, then this attribute
will be @code{None}.

If the @code{Progspace} is invalid, i.e.@:, when
@code{Progspace.is_valid()} returns @code{False}, then attempting to
access this attribute will raise a @code{RuntimeError} exception.
@end defvar

@defvar Progspace.executable_filename
The file name, as a string, of the executable file in use by this
program space.  The executable file is the file that @value{GDBN} will
invoke in order to start an inferior when using a native target.  The
file name within this attribute is updated by the @kbd{exec-file} and
@kbd{file} commands.

If no executable is currently set within this @code{Progspace} then
this attribute contains @code{None}.

If the @code{Progspace} is invalid, i.e.@:, when
@code{Progspace.is_valid()} returns @code{False}, then attempting to
access this attribute will raise a @code{RuntimeError} exception.
@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

@defvar Progspace.missing_debug_handlers
The @code{missing_debug_handlers} attribute is a list of the missing
debug handler objects for this program space.  @xref{Missing Debug
Info In Python}, for more information.
@end defvar

A program space has the following methods:

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

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

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

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

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

@defun Progspace.objfile_for_address (address)
Return the @code{gdb.Objfile} holding the given address, or
@code{None} if no objfile covers it.
@end defun

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

@xref{choosing attribute names}, for guidance on selecting a suitable
name for new attributes.

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
(@value{GDBP}) python
@group
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
@end group
@group
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
@end group
@group
(@value{GDBP}) file /tmp/hello
Reading symbols from /tmp/hello...
Computing the answer to the ultimate question ...
(@value{GDBP}) python print(gdb.current_progspace().expensive_computation)
42
(@value{GDBP}) run
Starting program: /tmp/hello
Hello.
[Inferior 1 (process 4242) exited normally]
@end group
@end smallexample

@node Objfiles In Python
@subsubsection Objfiles In Python

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

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

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

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

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

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

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

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

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

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

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

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

@defvar Objfile.is_file
An objfile often comes from an ordinary file, but in some cases it may
be constructed from the contents of memory.  This attribute is
@code{True} for file-backed objfiles, and @code{False} for other
kinds.
@end defvar

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

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

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

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

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

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

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

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

@xref{choosing attribute names}, for guidance on selecting a suitable
name for new attributes.

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

@smallexample
@group
(@value{GDBP}) 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
@end group
@group
(@value{GDBP}) file ./hello
Reading symbols from ./hello...
(@value{GDBP}) python print(gdb.objfiles()[0].time_loaded)
2014-10-09 11:41:36.770345
@end group
@end smallexample

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@item gdb.FRAME_UNWIND_OUTERMOST
This frame is the outermost.

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

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

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

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

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

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

@end defun

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

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

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

@defun Frame.older ()
Return the frame that called this frame.  If this is the oldest frame,
return @code{None}.
@end defun

@defun Frame.newer ()
Return the frame called by this frame.  If this is the newest frame,
return @code{None}.
@end defun

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

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

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

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

@defun Frame.static_link ()
In some languages (e.g., Ada, but also a GNU C extension), a nested
function can access the variables in the outer scope.  This is done
via a ``static link'', which is a reference from the nested frame to
the appropriate outer frame.

This method returns this frame's static link frame, if one exists.  If
there is no static link, this method returns @code{None}.
@end defun

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

@defun Frame.language ()
Return a string, the source language for this frame.
@end defun

@node Blocks In Python
@subsubsection Accessing blocks from Python

@cindex blocks in python
@tindex gdb.Block

In @value{GDBN}, symbols are stored in blocks.  A block corresponds
roughly to a scope in the source code.  Blocks are organized
hierarchically, and are represented individually in Python as a
@code{gdb.Block}.  Blocks rely on debugging information being
available.

A frame has a block.  Please see @ref{Frames In Python}, for a more
in-depth discussion of frames.

The outermost block is known as the @dfn{global block}.  The global
block typically holds public global variables and functions.

The block nested just inside the global block is the @dfn{static
block}.  The static block typically holds file-scoped variables and
functions.

@value{GDBN} provides a method to get a block's superblock, but there
is currently no way to examine the sub-blocks of a block, or to
iterate over all the blocks in a symbol table (@pxref{Symbol Tables In
Python}).

Here is a short example that should help explain blocks:

@smallexample
/* This is in the global block.  */
int global;

/* This is in the static block.  */
static int file_scope;

/* 'function' is in the global block, and 'argument' is
   in a block nested inside of 'function'.  */
int function (int argument)
@{
  /* 'local' is in a block inside 'function'.  It may or may
     not be in the same block as 'argument'.  */
  int local;

  @{
     /* 'inner' is in a block whose superblock is the one holding
        'local'.  */
     int inner;

     /* If this call is expanded by the compiler, you may see
        a nested block here whose function is 'inline_function'
        and whose superblock is the one holding 'inner'.  */
     inline_function ();
  @}
@}
@end smallexample

A @code{gdb.Block} is iterable.  The iterator returns the symbols
(@pxref{Symbols In Python}) local to the block.  Python programs
should not assume that a specific block object will always contain a
given symbol, since changes in @value{GDBN} features and
infrastructure may cause symbols move across blocks in a symbol
table.  You can also use Python's @dfn{dictionary syntax} to access
variables in this block, e.g.:

@smallexample
symbol = some_block['variable']  # symbol is of type gdb.Symbol
@end smallexample

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@node Symbols In Python
@subsubsection Python representation of Symbols

@cindex symbols in python
@tindex gdb.Symbol

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@defvar Symbol.is_variable
@code{True} if the symbol is a variable, as opposed to something like
a function or type.  Note that this also returns @code{False} for
arguments.
@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.

@vindex SYMBOL_FUNCTION_DOMAIN
@item gdb.SYMBOL_FUNCTION_DOMAIN
This domain contains functions.

@vindex SYMBOL_TYPE_DOMAIN
@item gdb.SYMBOL_TYPE_DOMAIN
This domain contains types.  In a C-like language, types using a tag
(the name appearing after a @code{struct}, @code{union}, or
@code{enum} keyword) will not appear here; in other languages, all
types are in this domain.

@vindex SYMBOL_STRUCT_DOMAIN
@item gdb.SYMBOL_STRUCT_DOMAIN
This domain holds struct, union and enum tag names.  This domain is
only used for C-like languages.  For example, in this code:
@smallexample
struct type_one @{ int x; @};
typedef struct type_one type_two;
@end smallexample
Here @code{type_one} will be in @code{SYMBOL_STRUCT_DOMAIN}, but
@code{type_two} will be in @code{SYMBOL_TYPE_DOMAIN}.

@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

When searching for a symbol, the desired domain constant can be passed
verbatim to the lookup function.  For example:
@smallexample
symbol = gdb.lookup_symbol ("name", domain=gdb.SYMBOL_VAR_DOMAIN)
@end smallexample

For more complex searches, there is a corresponding set of constants,
each named after one of the preceding constants, but with the
@samp{SEARCH} prefix replacing the @samp{SYMBOL} prefix; for example,
@code{SEARCH_LABEL_DOMAIN}.  These may be or'd together to form a
search constant, e.g.:
@smallexample
symbol = gdb.lookup_symbol ("name",
                            domain=gdb.SEARCH_VAR_DOMAIN | gdb.SEARCH_TYPE_DOMAIN)
@end smallexample

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@cindex line tables in python
@tindex gdb.LineTable

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

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

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

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

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

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

This will have the following output:

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

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

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

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

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

@node Breakpoints In Python
@subsubsection Manipulating breakpoints using Python

@cindex breakpoints in python
@tindex gdb.Breakpoint

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

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

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

The optional @var{type} argument specifies the type of the breakpoint to create,
as defined below.

The optional @var{wp_class} argument defines the class of watchpoint to create,
if @var{type} is @code{gdb.BP_WATCHPOINT}.  If @var{wp_class} is omitted, it
defaults to @code{gdb.WP_WRITE}.

The optional @var{internal} argument allows the breakpoint to become invisible
to the user.  The breakpoint will neither be reported when created, nor will it
be listed in the output from @code{info breakpoints} (but will be listed with
the @code{maint info breakpoints} command).

The optional @var{temporary} argument makes the breakpoint a temporary
breakpoint.  Temporary breakpoints are deleted after they have been hit.  Any
further access to the Python breakpoint after it has been hit will result in a
runtime error (as that breakpoint has now been automatically deleted).

The optional @var{qualified} argument is a boolean that allows interpreting
the function passed in @code{spec} as a fully-qualified name.  It is equivalent
to @code{break}'s @code{-qualified} flag (@pxref{Linespec Locations} and
@ref{Explicit Locations}).

@end defun

@defun Breakpoint.__init__ (@r{[} source @r{][}, function @r{][}, label @r{][}, line @r{]}, @r{][} internal @r{][}, temporary @r{][}, qualified @r{]})
This second form of creating a new breakpoint specifies the explicit
location (@pxref{Explicit Locations}) using keywords.  The new breakpoint will
be created in the specified source file @var{source}, at the specified
@var{function}, @var{label} and @var{line}.

@var{internal}, @var{temporary} and @var{qualified} have the same usage as
explained previously.
@end defun

The available types are represented by constants defined in the @code{gdb}
module:

@vtable @code
@vindex BP_BREAKPOINT
@item gdb.BP_BREAKPOINT
Normal code breakpoint.

@vindex BP_HARDWARE_BREAKPOINT
@item gdb.BP_HARDWARE_BREAKPOINT
Hardware assisted code breakpoint.

@vindex BP_WATCHPOINT
@item gdb.BP_WATCHPOINT
Watchpoint breakpoint.

@vindex BP_HARDWARE_WATCHPOINT
@item gdb.BP_HARDWARE_WATCHPOINT
Hardware assisted watchpoint.

@vindex BP_READ_WATCHPOINT
@item gdb.BP_READ_WATCHPOINT
Hardware assisted read watchpoint.

@vindex BP_ACCESS_WATCHPOINT
@item gdb.BP_ACCESS_WATCHPOINT
Hardware assisted access watchpoint.

@vindex BP_CATCHPOINT
@item gdb.BP_CATCHPOINT
Catchpoint.  Currently, this type can't be used when creating
@code{gdb.Breakpoint} objects, but will be present in
@code{gdb.Breakpoint} objects reported from
@code{gdb.BreakpointEvent}s (@pxref{Events In Python}).
@end vtable

The available watchpoint types are represented by constants defined in the
@code{gdb} module:

@vtable @code
@vindex WP_READ
@item gdb.WP_READ
Read only watchpoint.

@vindex WP_WRITE
@item gdb.WP_WRITE
Write only watchpoint.

@vindex WP_ACCESS
@item gdb.WP_ACCESS
Read/Write watchpoint.
@end vtable

@defun Breakpoint.stop (self)
The @code{gdb.Breakpoint} class can be sub-classed and, in
particular, you may choose to implement the @code{stop} method.
If this method is defined in a sub-class of @code{gdb.Breakpoint},
it will be called when the inferior reaches any location of a
breakpoint which instantiates that sub-class.  If the method returns
@code{True}, the inferior will be stopped at the location of the
breakpoint, otherwise the inferior will continue.

If there are multiple breakpoints at the same location with a
@code{stop} method, each one will be called regardless of the
return status of the previous.  This ensures that all @code{stop}
methods have a chance to execute at that location.  In this scenario
if one of the methods returns @code{True} but the others return
@code{False}, the inferior will still be stopped.

You should not alter the execution state of the inferior (i.e.@:, step,
next, etc.), alter the current frame context (i.e.@:, change the current
active frame), or alter, add or delete any breakpoint.  As a general
rule, you should not alter any data within @value{GDBN} or the inferior
at this time.

Example @code{stop} implementation:

@smallexample
class MyBreakpoint (gdb.Breakpoint):
      def stop (self):
        inf_val = gdb.parse_and_eval("foo")
        if inf_val == 3:
          return True
        return False
@end smallexample
@end defun

@defun Breakpoint.is_valid ()
Return @code{True} if this @code{Breakpoint} object is valid,
@code{False} otherwise.  A @code{Breakpoint} object can become invalid
if the user deletes the breakpoint.  In this case, the object still
exists, but the underlying breakpoint does not.  In the cases of
watchpoint scope, the watchpoint remains valid even if execution of the
inferior leaves the scope of that watchpoint.
@end defun

@defun Breakpoint.delete ()
Permanently deletes the @value{GDBN} breakpoint.  This also
invalidates the Python @code{Breakpoint} object.  Any further access
to this object's attributes or methods will raise an error.
@end defun

@defvar Breakpoint.enabled
This attribute is @code{True} if the breakpoint is enabled, and
@code{False} otherwise.  This attribute is writable.  You can use it to enable
or disable the breakpoint.
@end defvar

@defvar Breakpoint.silent
This attribute is @code{True} if the breakpoint is silent, and
@code{False} otherwise.  This attribute is writable.

Note that a breakpoint can also be silent if it has commands and the
first command is @code{silent}.  This is not reported by the
@code{silent} attribute.
@end defvar

@defvar Breakpoint.pending
This attribute is @code{True} if the breakpoint is pending, and
@code{False} otherwise.  @xref{Set Breaks}.  This attribute is
read-only.
@end defvar

@anchor{python_breakpoint_thread}
@defvar Breakpoint.thread
If the breakpoint is thread-specific (@pxref{Thread-Specific
Breakpoints}), this attribute holds the thread's global id.  If the
breakpoint is not thread-specific, this attribute is @code{None}.
This attribute is writable.

Only one of @code{Breakpoint.thread} or @code{Breakpoint.inferior} can
be set to a valid id at any time, that is, a breakpoint can be thread
specific, or inferior specific, but not both.
@end defvar

@anchor{python_breakpoint_inferior}
@defvar Breakpoint.inferior
If the breakpoint is inferior-specific (@pxref{Inferior-Specific
Breakpoints}), this attribute holds the inferior's id.  If the
breakpoint is not inferior-specific, this attribute is @code{None}.

This attribute can be written for breakpoints of type
@code{gdb.BP_BREAKPOINT} and @code{gdb.BP_HARDWARE_BREAKPOINT}.
@end defvar

@defvar Breakpoint.task
If the breakpoint is Ada task-specific, this attribute holds the Ada task
id.  If the breakpoint is not task-specific (or the underlying
language is not Ada), this attribute is @code{None}.  This attribute
is writable.
@end defvar

@defvar Breakpoint.ignore_count
This attribute holds the ignore count for the breakpoint, an integer.
This attribute is writable.
@end defvar

@defvar Breakpoint.number
This attribute holds the breakpoint's number --- the identifier used by
the user to manipulate the breakpoint.  This attribute is not writable.
@end defvar

@defvar Breakpoint.type
This attribute holds the breakpoint's type --- the identifier used to
determine the actual breakpoint type or use-case.  This attribute is not
writable.
@end defvar

@defvar Breakpoint.visible
This attribute tells whether the breakpoint is visible to the user
when set, or when the @samp{info breakpoints} command is run.  This
attribute is not writable.
@end defvar

@defvar Breakpoint.temporary
This attribute indicates whether the breakpoint was created as a
temporary breakpoint.  Temporary breakpoints are automatically deleted
after that breakpoint has been hit.  Access to this attribute, and all
other attributes and functions other than the @code{is_valid}
function, will result in an error after the breakpoint has been hit
(as it has been automatically deleted).  This attribute is not
writable.
@end defvar

@defvar Breakpoint.hit_count
This attribute holds the hit count for the breakpoint, an integer.
This attribute is writable, but currently it can only be set to zero.
@end defvar

@defvar Breakpoint.location
This attribute holds the location of the breakpoint, as specified by
the user.  It is a string.  If the breakpoint does not have a location
(that is, it is a watchpoint) the attribute's value is @code{None}.  This
attribute is not writable.
@end defvar

@defvar Breakpoint.locations
Get the most current list of breakpoint locations that are inserted for this
breakpoint, with elements of type @code{gdb.BreakpointLocation}
(described below).  This functionality matches that of the
@code{info breakpoint} command (@pxref{Set Breaks}), in that it only retrieves
the most current list of locations, thus the list itself when returned is
not updated behind the scenes.  This attribute is not writable.
@end defvar

@defvar Breakpoint.expression
This attribute holds a breakpoint expression, as specified by
the user.  It is a string.  If the breakpoint does not have an
expression (the breakpoint is not a watchpoint) the attribute's value
is @code{None}.  This attribute is not writable.
@end defvar

@defvar Breakpoint.condition
This attribute holds the condition of the breakpoint, as specified by
the user.  It is a string.  If there is no condition, this attribute's
value is @code{None}.  This attribute is writable.
@end defvar

@defvar Breakpoint.commands
This attribute holds the commands attached to the breakpoint.  If
there are commands, this attribute's value is a string holding all the
commands, separated by newlines.  If there are no commands, this
attribute is @code{None}.  This attribute is writable.
@end defvar

@subheading Breakpoint Locations

A breakpoint location is one of the actual places where a breakpoint has been
set, represented in the Python API by the @code{gdb.BreakpointLocation}
type.  This type is never instantiated by the user directly, but is retrieved
from @code{Breakpoint.locations} which returns a list of breakpoint
locations where it is currently set.  Breakpoint locations can become
invalid if new symbol files are loaded or dynamically loaded libraries are
closed.  Accessing the attributes of an invalidated breakpoint location will
throw a @code{RuntimeError} exception.  Access the @code{Breakpoint.locations}
attribute again to retrieve the new and valid breakpoints location list.

@defvar BreakpointLocation.source
This attribute returns the source file path and line number where this location
was set. The type of the attribute is a tuple of @var{string} and
@var{long}.  If the breakpoint location doesn't have a source location,
it returns None, which is the case for watchpoints and catchpoints.
This will throw a @code{RuntimeError} exception if the location
has been invalidated. This attribute is not writable.
@end defvar

@defvar BreakpointLocation.address
This attribute returns the address where this location was set.
This attribute is of type long.  This will throw a @code{RuntimeError}
exception if the location has been invalidated.  This attribute is
not writable.
@end defvar

@defvar BreakpointLocation.enabled
This attribute holds the value for whether or not this location is enabled.
This attribute is writable (boolean).  This will throw a @code{RuntimeError}
exception if the location has been invalidated.
@end defvar

@defvar BreakpointLocation.owner
This attribute holds a reference to the @code{gdb.Breakpoint} owner object,
from which this @code{gdb.BreakpointLocation} was retrieved from.
This will throw a @code{RuntimeError} exception if the location has been
invalidated.  This attribute is not writable.
@end defvar

@defvar BreakpointLocation.function
This attribute gets the name of the function where this location was set.
If no function could be found this attribute returns @code{None}.
This will throw a @code{RuntimeError} exception if the location has
been invalidated.  This attribute is not writable.
@end defvar

@defvar BreakpointLocation.fullname
This attribute gets the full name of where this location was set.  If no
full name could be found, this attribute returns @code{None}.
This will throw a @code{RuntimeError} exception if the location has
been invalidated.  This attribute is not writable.
@end defvar

@defvar BreakpointLocation.thread_groups
This attribute gets the thread groups it was set in.  It returns a @code{List}
of the thread group ID's.  This will throw a @code{RuntimeError}
exception if the location has been invalidated.  This attribute
is not writable.
@end defvar

@node Finish Breakpoints in Python
@subsubsection Finish Breakpoints

@cindex python finish breakpoints
@tindex gdb.FinishBreakpoint

A finish breakpoint is a temporary breakpoint set at the return address of
a frame, based on the @code{finish} command.  @code{gdb.FinishBreakpoint}
extends @code{gdb.Breakpoint}.  The underlying breakpoint will be disabled 
and deleted when the execution will run out of the breakpoint scope (i.e.@: 
@code{Breakpoint.stop} or @code{FinishBreakpoint.out_of_scope} triggered).
Finish breakpoints are thread specific and must be create with the right 
thread selected.  
 
@defun FinishBreakpoint.__init__ (@r{[}frame@r{]} @r{[}, internal@r{]})
Create a finish breakpoint at the return address of the @code{gdb.Frame}
object @var{frame}.  If @var{frame} is not provided, this defaults to the
newest frame.  The optional @var{internal} argument allows the breakpoint to
become invisible to the user.  @xref{Breakpoints In Python}, for further 
details about this argument.
@end defun

@defun FinishBreakpoint.out_of_scope (self)
In some circumstances (e.g.@: @code{longjmp}, C@t{++} exceptions, @value{GDBN} 
@code{return} command, @dots{}), a function may not properly terminate, and
thus never hit the finish breakpoint.  When @value{GDBN} notices such a
situation, the @code{out_of_scope} callback will be triggered.

You may want to sub-class @code{gdb.FinishBreakpoint} and override this
method:

@smallexample
class MyFinishBreakpoint (gdb.FinishBreakpoint)
    def stop (self):
        print ("normal finish")
        return True
    
    def out_of_scope ():
        print ("abnormal finish")
@end smallexample 
@end defun

@defvar FinishBreakpoint.return_value
When @value{GDBN} is stopped at a finish breakpoint and the frame 
used to build the @code{gdb.FinishBreakpoint} object had debug symbols, this
attribute will contain a @code{gdb.Value} object corresponding to the return
value of the function.  The value will be @code{None} if the function return 
type is @code{void} or if the return value was not computable.  This attribute
is not writable.
@end defvar

@node Lazy Strings In Python
@subsubsection Python representation of lazy strings

@cindex lazy strings in python
@tindex gdb.LazyString

A @dfn{lazy string} is a string whose contents is not retrieved or
encoded until it is needed.

A @code{gdb.LazyString} is represented in @value{GDBN} as an
@code{address} that points to a region of memory, an @code{encoding}
that will be used to encode that region of memory, and a @code{length}
to delimit the region of memory that represents the string.  The
difference between a @code{gdb.LazyString} and a string wrapped within
a @code{gdb.Value} is that a @code{gdb.LazyString} will be treated
differently by @value{GDBN} when printing.  A @code{gdb.LazyString} is
retrieved and encoded during printing, while a @code{gdb.Value}
wrapping a string is immediately retrieved and encoded on creation.

A @code{gdb.LazyString} object has the following functions:

@defun LazyString.value ()
Convert the @code{gdb.LazyString} to a @code{gdb.Value}.  This value
will point to the string in memory, but will lose all the delayed
retrieval, encoding and handling that @value{GDBN} applies to a
@code{gdb.LazyString}.
@end defun

@defvar LazyString.address
This attribute holds the address of the string.  This attribute is not
writable.
@end defvar

@defvar LazyString.length
This attribute holds the length of the string in characters.  If the
length is -1, then the string will be fetched and encoded up to the
first null of appropriate width.  This attribute is not writable.
@end defvar

@defvar LazyString.encoding
This attribute holds the encoding that will be applied to the string
when the string is printed by @value{GDBN}.  If the encoding is not
set, or contains an empty string,  then @value{GDBN} will select the
most appropriate encoding when the string is printed.  This attribute
is not writable.
@end defvar

@defvar LazyString.type
This attribute holds the type that is represented by the lazy string's
type.  For a lazy string this is a pointer or array type.  To
resolve this to the lazy string's character type, use the type's
@code{target} method.  @xref{Types In Python}.  This attribute is not
writable.
@end defvar

@node Architectures In Python
@subsubsection Python representation of architectures
@cindex Python architectures

@value{GDBN} uses architecture specific parameters and artifacts in a
number of its various computations.  An architecture is represented
by an instance of the @code{gdb.Architecture} class.

A @code{gdb.Architecture} class has the following methods:

@anchor{gdbpy_architecture_name}
@defun Architecture.name ()
Return the name (string value) of the architecture.
@end defun

@defun Architecture.disassemble (start_pc @r{[}, end_pc @r{[}, count@r{]]})
Return a list of disassembled instructions starting from the memory
address @var{start_pc}.  The optional arguments @var{end_pc} and
@var{count} determine the number of instructions in the returned list.
If both the optional arguments @var{end_pc} and @var{count} are
specified, then a list of at most @var{count} disassembled instructions
whose start address falls in the closed memory address interval from
@var{start_pc} to @var{end_pc} are returned.  If @var{end_pc} is not
specified, but @var{count} is specified, then @var{count} number of
instructions starting from the address @var{start_pc} are returned.  If
@var{count} is not specified but @var{end_pc} is specified, then all
instructions whose start address falls in the closed memory address
interval from @var{start_pc} to @var{end_pc} are returned.  If neither
@var{end_pc} nor @var{count} are specified, then a single instruction at
@var{start_pc} is returned.  For all of these cases, each element of the
returned list is a Python @code{dict} with the following string keys:

@table @code

@item addr
The value corresponding to this key is a Python long integer capturing
the memory address of the instruction.

@item asm
The value corresponding to this key is a string value which represents
the instruction with assembly language mnemonics.  The assembly
language flavor used is the same as that specified by the current CLI
variable @code{disassembly-flavor}.  @xref{Machine Code}.

@item length
The value corresponding to this key is the length (integer value) of the
instruction in bytes.

@end table
@end defun

@defun Architecture.integer_type (size @r{[}, signed@r{]})
This function looks up an integer type by its @var{size}, and
optionally whether or not it is signed.

@var{size} is the size, in bits, of the desired integer type.  Only
certain sizes are currently supported: 0, 8, 16, 24, 32, 64, and 128.

If @var{signed} is not specified, it defaults to @code{True}.  If
@var{signed} is @code{False}, the returned type will be unsigned.

If the indicated type cannot be found, this function will throw a
@code{ValueError} exception.
@end defun

@anchor{gdbpy_architecture_registers}
@defun Architecture.registers (@r{[} reggroup @r{]})
Return a @code{gdb.RegisterDescriptorIterator} (@pxref{Registers In
Python}) for all of the registers in @var{reggroup}, a string that is
the name of a register group.  If @var{reggroup} is omitted, or is the
empty string, then the register group @samp{all} is assumed.
@end defun

@anchor{gdbpy_architecture_reggroups}
@defun Architecture.register_groups ()
Return a @code{gdb.RegisterGroupsIterator} (@pxref{Registers In
Python}) for all of the register groups available for the
@code{gdb.Architecture}.
@end defun

@node Registers In Python
@subsubsection Registers In Python
@cindex Registers In Python

Python code can request from a @code{gdb.Architecture} information
about the set of registers available
(@pxref{gdbpy_architecture_registers,,@code{Architecture.registers}}).
The register information is returned as a
@code{gdb.RegisterDescriptorIterator}, which is an iterator that in
turn returns @code{gdb.RegisterDescriptor} objects.

A @code{gdb.RegisterDescriptor} does not provide the value of a
register (@pxref{gdbpy_frame_read_register,,@code{Frame.read_register}}
for reading a register's value), instead the @code{RegisterDescriptor}
is a way to discover which registers are available for a particular
architecture.

A @code{gdb.RegisterDescriptor} has the following read-only properties:

@defvar RegisterDescriptor.name
The name of this register.
@end defvar

It is also possible to lookup a register descriptor based on its name
using the following @code{gdb.RegisterDescriptorIterator} function:

@defun RegisterDescriptorIterator.find (name)
Takes @var{name} as an argument, which must be a string, and returns a
@code{gdb.RegisterDescriptor} for the register with that name, or
@code{None} if there is no register with that name.
@end defun

Python code can also request from a @code{gdb.Architecture}
information about the set of register groups available on a given
architecture
(@pxref{gdbpy_architecture_reggroups,,@code{Architecture.register_groups}}).

Every register can be a member of zero or more register groups.  Some
register groups are used internally within @value{GDBN} to control
things like which registers must be saved when calling into the
program being debugged (@pxref{Calling,,Calling Program Functions}).
Other register groups exist to allow users to easily see related sets
of registers in commands like @code{info registers}
(@pxref{info_registers_reggroup,,@code{info registers
@var{reggroup}}}).

The register groups information is returned as a
@code{gdb.RegisterGroupsIterator}, which is an iterator that in turn
returns @code{gdb.RegisterGroup} objects.

A @code{gdb.RegisterGroup} object has the following read-only
properties:

@defvar RegisterGroup.name
A string that is the name of this register group.
@end defvar

@node Connections In Python
@subsubsection Connections In Python
@cindex connections in python
@value{GDBN} lets you run and debug multiple programs in a single
session.  Each program being debugged has a connection, the connection
describes how @value{GDBN} controls the program being debugged.
Examples of different connection types are @samp{native} and
@samp{remote}.  @xref{Inferiors Connections and Programs}.

Connections in @value{GDBN} are represented as instances of
@code{gdb.TargetConnection}, or as one of its sub-classes.  To get a
list of all connections use @code{gdb.connections}
(@pxref{gdbpy_connections,,gdb.connections}).

To get the connection for a single @code{gdb.Inferior} read its
@code{gdb.Inferior.connection} attribute
(@pxref{gdbpy_inferior_connection,,gdb.Inferior.connection}).

Currently there is only a single sub-class of
@code{gdb.TargetConnection}, @code{gdb.RemoteTargetConnection},
however, additional sub-classes may be added in future releases of
@value{GDBN}.  As a result you should avoid writing code like:

@smallexample
conn = gdb.selected_inferior().connection
if type(conn) is gdb.RemoteTargetConnection:
  print("This is a remote target connection")
@end smallexample

@noindent
as this may fail when more connection types are added.  Instead, you
should write:

@smallexample
conn = gdb.selected_inferior().connection
if isinstance(conn, gdb.RemoteTargetConnection):
  print("This is a remote target connection")
@end smallexample

A @code{gdb.TargetConnection} has the following method:

@defun TargetConnection.is_valid ()
Return @code{True} if the @code{gdb.TargetConnection} object is valid,
@code{False} if not.  A @code{gdb.TargetConnection} will become
invalid if the connection no longer exists within @value{GDBN}, this
might happen when no inferiors are using the connection, but could be
delayed until the user replaces the current target.

Reading any of the @code{gdb.TargetConnection} properties will throw
an exception if the connection is invalid.
@end defun

A @code{gdb.TargetConnection} has the following read-only properties:

@defvar TargetConnection.num
An integer assigned by @value{GDBN} to uniquely identify this
connection.  This is the same value as displayed in the @samp{Num}
column of the @code{info connections} command output (@pxref{Inferiors
Connections and Programs,,info connections}).
@end defvar

@defvar TargetConnection.type
A string that describes what type of connection this is.  This string
will be one of the valid names that can be passed to the @code{target}
command (@pxref{Target Commands,,target command}).
@end defvar

@defvar TargetConnection.description
A string that gives a short description of this target type.  This is
the same string that is displayed in the @samp{Description} column of
the @code{info connection} command output (@pxref{Inferiors
Connections and Programs,,info connections}).
@end defvar

@defvar TargetConnection.details
An optional string that gives additional information about this
connection.  This attribute can be @code{None} if there are no
additional details for this connection.

An example of a connection type that might have additional details is
the @samp{remote} connection, in this case the details string can
contain the @samp{@var{hostname}:@var{port}} that was used to connect
to the remote target.
@end defvar

The @code{gdb.RemoteTargetConnection} class is a sub-class of
@code{gdb.TargetConnection}, and is used to represent @samp{remote}
and @samp{extended-remote} connections.  In addition to the attributes
and methods available from the @code{gdb.TargetConnection} base class,
a @code{gdb.RemoteTargetConnection} has the following method:

@kindex maint packet
@defun RemoteTargetConnection.send_packet (packet)
This method sends @var{packet} to the remote target and returns the
response.  The @var{packet} should either be a @code{bytes} object, or
a @code{Unicode} string.

If @var{packet} is a @code{Unicode} string, then the string is encoded
to a @code{bytes} object using the @sc{ascii} codec.  If the string
can't be encoded then an @code{UnicodeError} is raised.

If @var{packet} is not a @code{bytes} object, or a @code{Unicode}
string, then a @code{TypeError} is raised.  If @var{packet} is empty
then a @code{ValueError} is raised.

The response is returned as a @code{bytes} object.  If it is known
that the response can be represented as a string then this can be
decoded from the buffer.  For example, if it is known that the
response is an @sc{ascii} string:

@smallexample
remote_connection.send_packet("some_packet").decode("ascii")
@end smallexample

The prefix, suffix, and checksum (as required by the remote serial
protocol) are automatically added to the outgoing packet, and removed
from the incoming packet before the contents of the reply are
returned.

This is equivalent to the @code{maintenance packet} command
(@pxref{maint packet}).
@end defun

@node TUI Windows In Python
@subsubsection Implementing new TUI windows
@cindex Python TUI Windows

New TUI (@pxref{TUI}) windows can be implemented in Python.

@defun gdb.register_window_type (name, factory)
Because TUI windows are created and destroyed depending on the layout
the user chooses, new window types are implemented by registering a
factory function with @value{GDBN}.

@var{name} is the name of the new window.  It's an error to try to
replace one of the built-in windows, but other window types can be
replaced.  The @var{name} should match the regular expression
@code{[a-zA-Z][-_.a-zA-Z0-9]*}, it is an error to try and create a
window with an invalid name.

@var{function} is a factory function that is called to create the TUI
window.  This is called with a single argument of type
@code{gdb.TuiWindow}, described below.  It should return an object
that implements the TUI window protocol, also described below.
@end defun

As mentioned above, when a factory function is called, it is passed
an object of type @code{gdb.TuiWindow}.  This object has these
methods and attributes:

@defun TuiWindow.is_valid ()
This method returns @code{True} when this window is valid.  When the
user changes the TUI layout, windows no longer visible in the new
layout will be destroyed.  At this point, the @code{gdb.TuiWindow}
will no longer be valid, and methods (and attributes) other than
@code{is_valid} will throw an exception.

When the TUI is disabled using @code{tui disable} (@pxref{TUI
Commands,,tui disable}) the window is hidden rather than destroyed,
but @code{is_valid} will still return @code{False} and other methods
(and attributes) will still throw an exception.
@end defun

@defvar TuiWindow.width
This attribute holds the width of the window.  It is not writable.
@end defvar

@defvar TuiWindow.height
This attribute holds the height of the window.  It is not writable.
@end defvar

@defvar TuiWindow.title
This attribute holds the window's title, a string.  This is normally
displayed above the window.  This attribute can be modified.
@end defvar

@defun TuiWindow.erase ()
Remove all the contents of the window.
@end defun

@defun TuiWindow.write (string @r{[}, full_window@r{]})
Write @var{string} to the window.  @var{string} can contain ANSI
terminal escape styling sequences; @value{GDBN} will translate these
as appropriate for the terminal.

If the @var{full_window} parameter is @code{True}, then @var{string}
contains the full contents of the window.  This is similar to calling
@code{erase} before @code{write}, but avoids the flickering.
@end defun

The factory function that you supply should return an object
conforming to the TUI window protocol.  These are the method that can
be called on this object, which is referred to below as the ``window
object''.  The methods documented below are optional; if the object
does not implement one of these methods, @value{GDBN} will not attempt
to call it.  Additional new methods may be added to the window
protocol in the future.  @value{GDBN} guarantees that they will begin
with a lower-case letter, so you can start implementation methods with
upper-case letters or underscore to avoid any future conflicts.

@defun Window.close ()
When the TUI window is closed, the @code{gdb.TuiWindow} object will be
put into an invalid state.  At this time, @value{GDBN} will call
@code{close} method on the window object.

After this method is called, @value{GDBN} will discard any references
it holds on this window object, and will no longer call methods on
this object.
@end defun

@defun Window.render ()
In some situations, a TUI window can change size.  For example, this
can happen if the user resizes the terminal, or changes the layout.
When this happens, @value{GDBN} will call the @code{render} method on
the window object.

If your window is intended to update in response to changes in the
inferior, you will probably also want to register event listeners and
send output to the @code{gdb.TuiWindow}.
@end defun

@defun Window.hscroll (num)
This is a request to scroll the window horizontally.  @var{num} is the
amount by which to scroll, with negative numbers meaning to scroll
right.  In the TUI model, it is the viewport that moves, not the
contents.  A positive argument should cause the viewport to move
right, and so the content should appear to move to the left.
@end defun

@defun Window.vscroll (num)
This is a request to scroll the window vertically.  @var{num} is the
amount by which to scroll, with negative numbers meaning to scroll
backward.  In the TUI model, it is the viewport that moves, not the
contents.  A positive argument should cause the viewport to move down,
and so the content should appear to move up.
@end defun

@anchor{python-window-click}
@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).

When TUI mouse events are disabled by turning off the @code{tui mouse-events}
setting (@pxref{tui-mouse-events,,set tui mouse-events}), then @code{click} will
not be called.
@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 Missing Debug Info In Python
@subsubsection Missing Debug Info In Python
@cindex python, handle missing debug information

When @value{GDBN} encounters a new objfile (@pxref{Objfiles In
Python}), e.g.@: the primary executable, or any shared libraries used
by the inferior, @value{GDBN} will attempt to load the corresponding
debug information for that objfile.  The debug information might be
found within the objfile itself, or within a separate objfile which
@value{GDBN} will automatically locate and load.

Sometimes though, @value{GDBN} might not find any debug information
for an objfile, in this case the debugging experience will be
restricted.

If @value{GDBN} fails to locate any debug information for a particular
objfile, there is an opportunity for a Python extension to step in.  A
Python extension can potentially locate the missing debug information
using some platform- or project-specific steps, and inform
@value{GDBN} of its location.  Or a Python extension might provide
some platform- or project-specific advice to the user about how to
obtain the missing debug information.

A missing debug information Python extension consists of a handler
object which has the @code{name} and @code{enabled} attributes, and
implements the @code{__call__} method.  When @value{GDBN} encounters
an objfile for which it is unable to find any debug information, it
invokes the @code{__call__} method.  Full details of how handlers are
written can be found below.

@subheading The @code{gdb.missing_debug} Module

@value{GDBN} comes with a @code{gdb.missing_debug} module which
contains the following class and global function:

@deftp{class} gdb.missing_debug.MissingDebugHandler

@code{MissingDebugHandler} is a base class from which user-created
handlers can derive, though it is not required that handlers derive
from this class, so long as any user created handler has the
@code{name} and @code{enabled} attributes, and implements the
@code{__call__} method.

@defun MissingDebugHandler.__init__ (name)
The @var{name} is a string used to reference this missing debug
handler within some @value{GDBN} commands.  Valid names consist of the
characters @code{[-_a-zA-Z0-9]}, creating a handler with an invalid
name raises a @code{ValueError} exception.
@end defun

@defun MissingDebugHandler.__call__ (objfile)
Sub-classes must override the @code{__call__} method.  The
@var{objfile} argument will be a @code{gdb.Objfile}, this is the
objfile for which @value{GDBN} was unable to find any debug
information.

The return value from the @code{__call__} method indicates what
@value{GDBN} should do next.  The possible return values are:

@itemize @bullet
@item @code{None}

This indicates that this handler could not help with @var{objfile},
@value{GDBN} should call any other registered handlers.

@item @code{True}

This indicates that this handler has installed the debug information
into a location where @value{GDBN} would normally expect to find it
when looking for separate debug information files (@pxref{Separate
Debug Files}).  @value{GDBN} will repeat the normal lookup process,
which should now find the separate debug file.

If @value{GDBN} still doesn't find the separate debug information file
after this second attempt, then the Python missing debug information
handlers are not invoked a second time, this prevents a badly behaved
handler causing @value{GDBN} to get stuck in a loop.  @value{GDBN}
will continue without any debug information for @var{objfile}.

@item @code{False}

This indicates that this handler has done everything that it intends
to do with @var{objfile}, but no separate debug information can be
found.  @value{GDBN} will not call any other registered handlers for
@var{objfile}.  @value{GDBN} will continue without debugging
information for @var{objfile}.

@item A string

The returned string should contain a filename.  @value{GDBN} will not
call any further registered handlers, and will instead load the debug
information from the file identified by the returned filename.
@end itemize

Invoking the @code{__call__} method from this base class will raise a
@code{NotImplementedError} exception.
@end defun

@defvar MissingDebugHandler.name
A read-only attribute which is a string, the name of this handler
passed to the @code{__init__} method.
@end defvar

@defvar MissingDebugHandler.enabled
A modifiable attribute containing a boolean; when @code{True}, the
handler is enabled, and will be used by @value{GDBN}.  When
@code{False}, the handler has been disabled, and will not be used.
@end defvar
@end deftp

@defun gdb.missing_debug.register_handler (locus, handler, replace=@code{False})
Register a new missing debug handler with @value{GDBN}.

@var{handler} is an instance of a sub-class of
@code{MissingDebugHandler}, or at least an instance of an object that
has the same attributes and methods as @code{MissingDebugHandler}.

@var{locus} specifies to which handler list to prepend @var{handler}.
It can be either a @code{gdb.Progspace} (@pxref{Progspaces In Python})
or @code{None}, in which case the handler is registered globally.  The
newly registered @var{handler} will be called before any other handler
from the same locus.  Two handlers in the same locus cannot have the
same name, an attempt to add a handler with an already existing name
raises an exception unless @var{replace} is @code{True}, in which case
the old handler is deleted and the new handler is prepended to the
selected handler list.

@value{GDBN} first calls the handlers for the current program space,
and then the globally registered handlers.  As soon as a handler
returns a value other than @code{None}, no further handlers are called
for this objfile.
@end defun

@node Python Auto-loading
@subsection Python Auto-loading
@cindex Python auto-loading

When a new object file is read (for example, due to the @code{file}
command, or because the inferior has loaded a shared library),
@value{GDBN} will look for Python support scripts in several ways:
@file{@var{objfile}-gdb.py} and @code{.debug_gdb_scripts} section.
@xref{Auto-loading extensions}.

The auto-loading feature is useful for supplying application-specific
debugging commands and scripts.

Auto-loading can be enabled or disabled,
and the list of auto-loaded scripts can be printed.

@table @code
@anchor{set auto-load python-scripts}
@kindex set auto-load python-scripts
@item set auto-load python-scripts [on|off]
Enable or disable the auto-loading of Python scripts.

@anchor{show auto-load python-scripts}
@kindex show auto-load python-scripts
@item show auto-load python-scripts
Show whether auto-loading of Python scripts is enabled or disabled.

@anchor{info auto-load python-scripts}
@kindex info auto-load python-scripts
@cindex print list of auto-loaded Python scripts
@item info auto-load python-scripts [@var{regexp}]
Print the list of all Python scripts that @value{GDBN} auto-loaded.

Also printed is the list of Python scripts that were mentioned in
the @code{.debug_gdb_scripts} section and were either not found
(@pxref{dotdebug_gdb_scripts section}) or were not auto-loaded due to
@code{auto-load safe-path} rejection (@pxref{Auto-loading}).
This is useful because their names are not printed when @value{GDBN}
tries to load them and fails.  There may be many of them, and printing
an error message for each one is problematic.

If @var{regexp} is supplied only Python scripts with matching names are printed.

Example:

@smallexample
(gdb) info auto-load python-scripts
Loaded Script
Yes    py-section-script.py
       full name: /tmp/py-section-script.py
No     my-foo-pretty-printers.py
@end smallexample
@end table

When reading an auto-loaded file or script, @value{GDBN} sets the
@dfn{current objfile}.  This is available via the @code{gdb.current_objfile}
function (@pxref{Objfiles In Python}).  This can be useful for
registering objfile-specific pretty-printers and frame-filters.

@node Python modules
@subsection Python modules
@cindex python modules

@value{GDBN} comes with several modules to assist writing Python code.

@menu
* gdb.printing::       Building and registering pretty-printers.
* gdb.types::          Utilities for working with types.
* gdb.prompt::         Utilities for prompt value substitution.
@end menu

@node gdb.printing
@subsubsection gdb.printing
@cindex gdb.printing

This module provides a collection of utilities for working with
pretty-printers.

@table @code
@item PrettyPrinter (@var{name}, @var{subprinters}=None)
This class specifies the API that makes @samp{info pretty-printer},
@samp{enable pretty-printer} and @samp{disable pretty-printer} work.
Pretty-printers should generally inherit from this class.

@item SubPrettyPrinter (@var{name})
For printers that handle multiple types, this class specifies the
corresponding API for the subprinters.

@item RegexpCollectionPrettyPrinter (@var{name})
Utility class for handling multiple printers, all recognized via
regular expressions.
@xref{Writing a Pretty-Printer}, for an example.

@item FlagEnumerationPrinter (@var{name})
A pretty-printer which handles printing of @code{enum} values.  Unlike
@value{GDBN}'s built-in @code{enum} printing, this printer attempts to
work properly when there is some overlap between the enumeration
constants.  The argument @var{name} is the name of the printer and
also the name of the @code{enum} type to look up.

@item register_pretty_printer (@var{obj}, @var{printer}, @var{replace}=False)
Register @var{printer} with the pretty-printer list of @var{obj}.
If @var{replace} is @code{True} then any existing copy of the printer
is replaced.  Otherwise a @code{RuntimeError} exception is raised
if a printer with the same name already exists.
@end table

@node gdb.types
@subsubsection gdb.types
@cindex gdb.types

This module provides a collection of utilities for working with
@code{gdb.Type} objects.

@table @code
@item get_basic_type (@var{type})
Return @var{type} with const and volatile qualifiers stripped,
and with typedefs and C@t{++} references converted to the underlying type.

C@t{++} example:

@smallexample
typedef const int const_int;
const_int foo (3);
const_int& foo_ref (foo);
int main () @{ return 0; @}
@end smallexample

Then in gdb:

@smallexample
(gdb) start
(gdb) python import gdb.types
(gdb) python foo_ref = gdb.parse_and_eval("foo_ref")
(gdb) python print gdb.types.get_basic_type(foo_ref.type)
int
@end smallexample

@item has_field (@var{type}, @var{field})
Return @code{True} if @var{type}, assumed to be a type with fields
(e.g., a structure or union), has field @var{field}.

@item make_enum_dict (@var{enum_type})
Return a Python @code{dictionary} type produced from @var{enum_type}.

@item deep_items (@var{type})
Returns a Python iterator similar to the standard
@code{gdb.Type.iteritems} method, except that the iterator returned
by @code{deep_items} will recursively traverse anonymous struct or
union fields.  For example:

@smallexample
struct A
@{
    int a;
    union @{
        int b0;
        int b1;
    @};
@};
@end smallexample

@noindent
Then in @value{GDBN}:
@smallexample
(@value{GDBP}) python import gdb.types
(@value{GDBP}) python struct_a = gdb.lookup_type("struct A")
(@value{GDBP}) python print struct_a.keys ()
@{['a', '']@}
(@value{GDBP}) python print [k for k,v in gdb.types.deep_items(struct_a)]
@{['a', 'b0', 'b1']@}
@end smallexample

@item get_type_recognizers ()
Return a list of the enabled type recognizers for the current context.
This is called by @value{GDBN} during the type-printing process
(@pxref{Type Printing API}).

@item apply_type_recognizers (recognizers, type_obj)
Apply the type recognizers, @var{recognizers}, to the type object
@var{type_obj}.  If any recognizer returns a string, return that
string.  Otherwise, return @code{None}.  This is called by
@value{GDBN} during the type-printing process (@pxref{Type Printing
API}).

@item register_type_printer (locus, printer)
This is a convenience function to register a type printer
@var{printer}.  The printer must implement the type printer protocol.
The @var{locus} argument is either a @code{gdb.Objfile}, in which case
the printer is registered with that objfile; a @code{gdb.Progspace},
in which case the printer is registered with that progspace; or
@code{None}, in which case the printer is registered globally.

@item TypePrinter
This is a base class that implements the type printer protocol.  Type
printers are encouraged, but not required, to derive from this class.
It defines a constructor:

@defmethod TypePrinter __init__ (self, name)
Initialize the type printer with the given name.  The new printer
starts in the enabled state.
@end defmethod

@end table

@node gdb.prompt
@subsubsection gdb.prompt
@cindex gdb.prompt

This module provides a method for prompt value-substitution.

@table @code
@item substitute_prompt (@var{string})
Return @var{string} with escape sequences substituted by values.  Some
escape sequences take arguments.  You can specify arguments inside
``@{@}'' immediately following the escape sequence.

The escape sequences you can pass to this function are:

@table @code
@item \\
Substitute a backslash.
@item \e
Substitute an ESC character.
@item \f
Substitute the selected frame; an argument names a frame parameter.
@item \n
Substitute a newline.
@item \p
Substitute a parameter's value; the argument names the parameter.
@item \r
Substitute a carriage return.
@item \t
Substitute the selected thread; an argument names a thread parameter.
@item \v
Substitute the version of GDB.
@item \w
Substitute the current working directory.
@item \[
Begin a sequence of non-printing characters.  These sequences are
typically used with the ESC character, and are not counted in the string
length.  Example: ``\[\e[0;34m\](gdb)\[\e[0m\]'' will return a
blue-colored ``(gdb)'' prompt where the length is five.
@item \]
End a sequence of non-printing characters.
@end table

For example:

@smallexample
substitute_prompt ("frame: \f, args: \p@{print frame-arguments@}")
@end smallexample

@exdent will return the string:

@smallexample
"frame: main, args: scalars"
@end smallexample
@end table
