-@c Copyright (C) 2008--2022 Free Software Foundation, Inc.
+@c Copyright (C) 2008--2023 Free Software Foundation, Inc.
@c Permission is granted to copy, distribute and/or modify this document
@c under the terms of the GNU Free Documentation License, Version 1.3 or
@c any later version published by the Free Software Foundation; with the
option must be placed into the early initialization file
(@pxref{Initialization Files}) to have the desired effect.
-By default this option is set to @samp{auto}, in this mode Python will
-check the environment variable @env{PYTHONDONTWRITEBYTECODE} to see
+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.
* 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.
+* Type Printing API:: Pretty-printing types.
* Frame Filter API:: Filtering Frames.
* Frame Decorator API:: Decorating Frames.
* Writing a Frame Filter:: Writing a Frame Filter.
* 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.
+* Connections In Python:: Python representation of connections.
* TUI Windows In Python:: Implementing new TUI windows.
+* Disassembly In Python:: Instruction Disassembly In Python
@end menu
@node Basic Python
@end defun
@findex gdb.flush
-@defun gdb.flush ()
+@defun gdb.flush (@r{[}, stream@r{]})
Flush the buffer of a @value{GDBN} paginated stream so that the
contents are displayed immediately. @value{GDBN} will flush the
contents of a stream automatically when it encounters a newline in the
that match the expression represented as @code{gdb.Symtab_and_line}
objects (@pxref{Symbol Tables In Python}). If @var{expression} is
provided, it is decoded the way that @value{GDBN}'s inbuilt
-@code{break} or @code{edit} commands do (@pxref{Specify Location}).
+@code{break} or @code{edit} commands do (@pxref{Location
+Specifications}).
@end defun
@defun gdb.prompt_hook (current_prompt)
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
@end smallexample
@end defun
+@defun gdb.current_language ()
+Return the name of the current language as a string. Unlike
+@code{gdb.parameter('language')}, this function will never return
+@samp{auto}. If a @code{gdb.Frame} object is available (@pxref{Frames
+In Python}), the @code{language} method might be preferable in some
+cases, as that is not affected by the user's language setting.
+@end defun
+
@node Exception Handling
@subsubsection Exception Handling
@cindex python exceptions
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
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
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
@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}
printer exists, then this returns @code{None}.
@end defun
+Normally, a pretty-printer can respect the user's print settings
+(including temporarily applied settings, such as @samp{/x}) simply by
+calling @code{Value.format_string} (@pxref{Values From Inferior}).
+However, these settings can also be queried directly:
+
+@findex gdb.print_options
+@defun gdb.print_options ()
+Return a dictionary whose keys are the valid keywords that can be
+given to @code{Value.format_string}, and whose values are the user's
+settings. During a @code{print} or other operation, the values will
+reflect any flags that are temporarily in effect.
+
+@smallexample
+(gdb) python print (gdb.print_options ()['max_elements'])
+200
+@end smallexample
+@end defun
+
@node Selecting Pretty-Printers
@subsubsection Selecting Pretty-Printers
@cindex selecting python pretty-printers
@defun PendingFrame.create_unwind_info (frame_id)
Returns a new @code{gdb.UnwindInfo} instance identified by given
-@var{frame_id}. The argument is used to build @value{GDBN}'s frame ID
-using one of functions provided by @value{GDBN}. @var{frame_id}'s attributes
-determine which function will be used, as follows:
+@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
@var{value} is a register value (a @code{gdb.Value} object).
@end defun
+@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
@value{GDBN} comes with the module containing the base @code{Unwinder}
follows:
@smallexample
-from gdb.unwinders import Unwinder
+from gdb.unwinder import Unwinder
class FrameId(object):
def __init__(self, sp, pc):
class MyUnwinder(Unwinder):
- def __init__(....):
- super(MyUnwinder, self).__init___(<expects unwinder name argument>)
+ def __init__(self):
+ super().__init___("MyUnwinder_Name")
- def __call__(pending_frame):
+ def __call__(self, pending_frame):
if not <we recognize frame>:
return None
- # Create UnwindInfo. Usually the frame is identified by the stack
- # pointer and the program counter.
- sp = pending_frame.read_register(<SP number>)
- pc = pending_frame.read_register(<PC number>)
+
+ # 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
+ # Find the values of the registers in the caller's frame and
# save them in the result:
- unwind_info.add_saved_register(<register>, <value>)
+ unwind_info.add_saved_register(<register-number>, <register-value>)
....
# Return the result:
return unwind_info
+gdb.unwinder.register_unwinder(<locus>, MyUnwinder(), <replace>)
@end smallexample
-@subheading Registering a Unwinder
-
-An object file, a program space, and the @value{GDBN} proper can have
-unwinders registered with it.
-
-The @code{gdb.unwinders} module provides the function to register a
-unwinder:
-
-@defun gdb.unwinder.register_unwinder (locus, unwinder, replace=False)
-@var{locus} is specifies an object file or a program space to which
-@var{unwinder} is added. Passing @code{None} or @code{gdb} adds
-@var{unwinder} to the @value{GDBN}'s global unwinder list. The newly
-added @var{unwinder} will be called before any other unwinder from the
-same locus. Two unwinders in the same locus cannot have the same
-name. An attempt to add a unwinder with already existing name raises
-an exception unless @var{replace} is @code{True}, in which case the
-old unwinder is deleted.
-@end defun
-
-@subheading Unwinder Precedence
-
-@value{GDBN} first calls the unwinders from all the object files in no
-particular order, then the unwinders from the current program space,
-and finally the unwinders from @value{GDBN}.
-
@node Xmethods In Python
@subsubsection Xmethods In Python
@cindex xmethods in Python
@noindent
then, after loading the Python script defining the xmethod matchers
-and workers into @code{GDBN}, invoking the method @code{geta} or using
+and workers into @value{GDBN}, invoking the method @code{geta} or using
the operator @code{+} on @code{obj} will invoke the xmethods
defined above:
particular frame (@pxref{Frames In Python}).
@end defun
+@anchor{gdbpy_inferior_read_memory}
@findex Inferior.read_memory
@defun Inferior.read_memory (address, length)
Read @var{length} addressable memory units from the inferior, starting at
@end defvar
@defvar BreakpointEvent.breakpoint
-A reference to the first breakpoint that was hit.
-This function is maintained for backward compatibility and is now deprecated
-in favor of the @code{gdb.BreakpointEvent.breakpoints} attribute.
+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
@xref{Objfiles In Python}, for details of the @code{gdb.Objfile} object.
@end defvar
+@item events.free_objfile
+Emits @code{gdb.FreeObjFileEvent} which indicates that an object file
+is about to be removed from @value{GDBN}. One reason this can happen
+is when the inferior calls @code{dlclose}.
+@code{gdb.FreeObjFileEvent} has one attribute:
+
+@defvar NewObjFileEvent.objfile
+A reference to the object file (@code{gdb.Objfile}) which will be unloaded.
+@xref{Objfiles In Python}, for details of the @code{gdb.Objfile} object.
+@end defvar
+
@item events.clear_objfiles
Emits @code{gdb.ClearObjFilesEvent} which indicates that the list of object
files for a program space has been reset.
@defun Command.dont_repeat ()
By default, a @value{GDBN} command is repeated when the user enters a
blank line at the command prompt. A command can suppress this
-behavior by invoking the @code{dont_repeat} method. This is similar
-to the user command @code{dont-repeat}, see @ref{Define, dont-repeat}.
+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)
@vindex COMPLETE_LOCATION
@item gdb.COMPLETE_LOCATION
This constant means that location completion should be done.
-@xref{Specify Location}.
+@xref{Location Specifications}.
@vindex COMPLETE_COMMAND
@item gdb.COMPLETE_COMMAND
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 place.
+this command installed in its stead.
@end defvar
-The following code snippet shows how a two trivial MI command can be
+The following code snippet shows how some trivial MI commands can be
implemented in Python:
@smallexample
@findex PARAM_UINTEGER
@findex gdb.PARAM_UINTEGER
@item gdb.PARAM_UINTEGER
-The value is an unsigned integer. The value of 0 should be
-interpreted to mean ``unlimited''.
+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 0 should be interpreted
-to mean ``unlimited''.
+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
@findex PARAM_ZINTEGER
@findex gdb.PARAM_ZINTEGER
@item gdb.PARAM_ZINTEGER
-The value is an integer. This is like @code{PARAM_INTEGER}, except 0
-is interpreted as itself.
+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_INTEGER},
-except 0 is interpreted as itself, and the value cannot be negative.
+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_ZUINTEGER},
-except the special value -1 should be interpreted to mean
-``unlimited''. Other negative values are not allowed.
+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
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.
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
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
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
@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.
+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
values can be 1 (left), 2 (middle), or 3 (right).
@end defun
+@node Disassembly In Python
+@subsubsection Instruction Disassembly In Python
+@cindex python instruction disassembly
+
+@value{GDBN}'s builtin disassembler can be extended, or even replaced,
+using the Python API. The disassembler related features are contained
+within the @code{gdb.disassembler} module:
+
+@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
+@end deftp
+
+@deftp {class} 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
+
+@deftp {class} DisassemblerResult
+This class is used to hold the result of calling
+@w{@code{Disassembler.__call__}}, and represents a single disassembled
+instruction. This class has the following properties and methods:
+
+@defun DisassemblerResult.__init__ (@var{length}, @var{string})
+Initialize an instance of this class, @var{length} is the length of
+the disassembled instruction in bytes, which must be greater than
+zero, and @var{string} is a non-empty string that represents the
+disassembled instruction.
+@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.
+@end defvar
+@end deftp
+
+The following functions are also contained in the
+@code{gdb.disassembler} module:
+
+@defun register_disassembler (disassembler, architecture)
+The @var{disassembler} must be a sub-class of
+@code{gdb.disassembler.Disassembler} or @code{None}.
+
+The optional @var{architecture} is either a string, or the value
+@code{None}. If it is a string, then it should be the name of an
+architecture known to @value{GDBN}, as returned either from
+@code{gdb.Architecture.name}
+(@pxref{gdbpy_architecture_name,,gdb.Architecture.name}), or from
+@code{gdb.architecture_names}
+(@pxref{gdb_architecture_names,,gdb.architecture_names}).
+
+The @var{disassembler} will be installed for the architecture named by
+@var{architecture}, or if @var{architecture} is @code{None}, then
+@var{disassembler} will be installed as a global disassembler for use
+by all architectures.
+
+@cindex disassembler in Python, global vs.@: specific
+@cindex search order for disassembler in Python
+@cindex look up of disassembler in Python
+@value{GDBN} only records a single disassembler for each architecture,
+and a single global disassembler. Calling
+@code{register_disassembler} for an architecture, or for the global
+disassembler, will replace any existing disassembler registered for
+that @var{architecture} value. The previous disassembler is returned.
+
+If @var{disassembler} is @code{None} then any disassembler currently
+registered for @var{architecture} is deregistered and returned.
+
+When @value{GDBN} is looking for a disassembler to use, @value{GDBN}
+first looks for an architecture specific disassembler. If none has
+been registered then @value{GDBN} looks for a global disassembler (one
+registered with @var{architecture} set to @code{None}). Only one
+disassembler is called to perform disassembly, so, if there is both an
+architecture specific disassembler, and a global disassembler
+registered, it is the architecture specific disassembler that will be
+used.
+
+@value{GDBN} tracks the architecture specific, and global
+disassemblers separately, so it doesn't matter in which order
+disassemblers are created or registered; an architecture specific
+disassembler, if present, will always be used in preference to a
+global disassembler.
+
+You can use the @kbd{maint info python-disassemblers} command
+(@pxref{maint info python-disassemblers}) to see which disassemblers
+have been registered.
+@end defun
+
+@anchor{builtin_disassemble}
+@defun builtin_disassemble (info)
+This function calls back into @value{GDBN}'s builtin disassembler to
+disassemble the instruction identified by @var{info}, an instance, or
+sub-class, of @code{DisassembleInfo}.
+
+When the builtin disassembler needs to read memory the
+@code{read_memory} method on @var{info} will be called. By
+sub-classing @code{DisassembleInfo} and overriding the
+@code{read_memory} method, it is possible to intercept calls to
+@code{read_memory} from the builtin disassembler, and to modify the
+values returned.
+
+It is important to understand that, even when
+@code{DisassembleInfo.read_memory} raises a @code{gdb.MemoryError}, it
+is the internal disassembler itself that reports the memory error to
+@value{GDBN}. The reason for this is that the disassembler might
+probe memory to see if a byte is readable or not; if the byte can't be
+read then the disassembler may choose not to report an error, but
+instead to disassemble the bytes that it does have available.
+
+If the builtin disassembler is successful then an instance of
+@code{DisassemblerResult} is returned from @code{builtin_disassemble},
+alternatively, if something goes wrong, an exception will be raised.
+
+A @code{MemoryError} will be raised if @code{builtin_disassemble} is
+unable to read some memory that is required in order to perform
+disassembly correctly.
+
+Any exception that is not a @code{MemoryError}, that is raised in a
+call to @code{read_memory}, will pass through
+@code{builtin_disassemble}, and be visible to the caller.
+
+Finally, there are a few cases where @value{GDBN}'s builtin
+disassembler can fail for reasons that are not covered by
+@code{MemoryError}. In these cases, a @code{GdbError} will be raised.
+The contents of the exception will be a string describing the problem
+the disassembler encountered.
+@end defun
+
+Here is an example that registers a global disassembler. The new
+disassembler invokes the builtin disassembler, and then adds a
+comment, @code{## Comment}, to each line of disassembly output:
+
+@smallexample
+class ExampleDisassembler(gdb.disassembler.Disassembler):
+ def __init__(self):
+ super().__init__("ExampleDisassembler")
+
+ def __call__(self, info):
+ result = gdb.disassembler.builtin_disassemble(info)
+ length = result.length
+ text = result.string + "\t## Comment"
+ return gdb.disassembler.DisassemblerResult(length, text)
+
+gdb.disassembler.register_disassembler(ExampleDisassembler())
+@end smallexample
+
+The following example creates a sub-class of @code{DisassembleInfo} in
+order to intercept the @code{read_memory} calls, within
+@code{read_memory} any bytes read from memory have the two 4-bit
+nibbles swapped around. This isn't a very useful adjustment, but
+serves as an example.
+
+@smallexample
+class MyInfo(gdb.disassembler.DisassembleInfo):
+ def __init__(self, info):
+ super().__init__(info)
+
+ def read_memory(self, length, offset):
+ buffer = super().read_memory(length, offset)
+ result = bytearray()
+ for b in buffer:
+ v = int.from_bytes(b, 'little')
+ v = (v << 4) & 0xf0 | (v >> 4)
+ result.append(v)
+ return memoryview(result)
+
+class NibbleSwapDisassembler(gdb.disassembler.Disassembler):
+ def __init__(self):
+ super().__init__("NibbleSwapDisassembler")
+
+ def __call__(self, info):
+ info = MyInfo(info)
+ return gdb.disassembler.builtin_disassemble(info)
+
+gdb.disassembler.register_disassembler(NibbleSwapDisassembler())
+@end smallexample
+
@node Python Auto-loading
@subsection Python Auto-loading
@cindex Python auto-loading