Automation API: extending UDB¶
The debugger_extensions
package provides functionalities which can be used from inside
the debugger.
Most of the functionalities as provided through the udb
object (see
the documentation on its interface for details) in the
debugger_extensions
module, but the module also provides other utility functions and
types.
Inferface for the udb
object¶
The following classes represent the interface of the udb
object in the
debugger_extensions
module and they cannot be instantiated by the user.
- class debugger_extensions.controller.Recording¶
Groups methods related to recording files.
Access this as
udb.recording
. For instance, to load a recording, do:from undodb.debugger_extensions import udb udb.recording.load('recording_file_name.undo')
- load(recording_filename: pathlib.Path | str) None ¶
Loads the recording for the execution of a program from the specified file.
This method corresponds to the functionality provided by the
uload
command.- Parameters
recording_filename (
Path | str
) – The path of the file to load.- Raises
debugger_extensions.LoadError – If the loading of the recording fails.
- save(recording_filename: pathlib.Path | str | None) pathlib.Path ¶
Saves the current execution history to the specified file.
This method corresponds to the functionality provided by the
usave
command.- Parameters
recording_filename (
Path | str | None
) – The path of the recording file to save orNone
to automatically generate an appropriate file name.- Returns
The path where the recording was saved. This is useful is
None
was passed as path.- Return type
Path
- Raises
SaveError – If the saving fails.
- class debugger_extensions.controller.Time¶
Groups methods related to times in execution history.
Access this as
udb.time
. For instance, to go to the end of the execution history, do:from undodb.debugger_extensions import udb udb.time.goto_end()
For details on how UDB represents time, see UDB time notation.
- auto_reverting() Iterator[None] ¶
Context manager to automatically revert to the current time at the beginning of the block when execution leaves it.
This can be used to do some
goto
or similar operations and then revert the time:with udb.time.auto_reverting(): udb.time.goto_start() ... udb.time.goto(...) ... ...
- get() debugger_extensions._udb_wrapper.Time ¶
Gets the current time in execution history.
- Returns
The current time in execution history.
- Return type
- get_wallclock_extent() tuple[datetime.datetime, datetime.datetime] ¶
Gets the wall clock time corresponding to the start and end of the recorded history of the currently running process or loaded LiveRecorder recording.
- Returns
A tuple with the start and end times as UTC
datetime
instances. The first element is the time when recording of the target process started. The second element is the time when the recording session stopped for LiveRecorder recordings; for live debugging sessions it’s the current time (as debugging has not terminated yet).
- goto(time: debugger_extensions._udb_wrapper.Time | int) None ¶
Goes to the specified time in execution history.
- Parameters
time (
debugger_extensions.Time
|int
) – The time to go to. It can be either adebugger_extensions.Time
or, for convenience, just an integer representing the bbcount.
- goto_end()¶
Go to the latest time in recording history.
- goto_start()¶
Goes to the earliest time in recording history.
- class debugger_extensions.controller.Udb¶
The main component to control UDB.
- get_event_log_extent()¶
Gets the range of bbcounts available in recorded history.
- Returns
A named tuple representing the range of bbcounts. The first element (also accessible as
start
) is the oldest point in recorded history. The second element (also accessible asend
) is the most recent point in recorded history.
- get_signal_info()¶
Returns the details of the latest signal sent to the debugged program.
- Returns
An object describing the latest signal delivered or
None
if this information is not available, for instance because no program is running.- Return type
(
debugger_extensions.SigInfo
|None
)
The debugger_extensions
package¶
Package for code available only to extensions running inside UDB.
- debugger_extensions.udb¶
The main object used to access UDB functionalities, see the documentation on its interface.
- exception debugger_extensions.LoadError(filename: pathlib.Path, msg: str)¶
An error occurred while trying to load a recording.
- exception debugger_extensions.NotRecordingError(*args: Any, **kwargs: Any)¶
Raised while in deferred recording mode if UDB tries to execute an operation which requires the debugged process to be recorded.
This happens, for instance, if a reverse-execution command is used in deferred recording mode.
- exception debugger_extensions.NotRunningError(*args: Any, **kwargs: Any)¶
Raised if UDB tries to execute an operation which requires the debugged process to be running, but the process was not started.
This happens, for instance, if a command like
next
is used before running the process with therun
,start
orstarti
commands.
- class debugger_extensions.RecordingTime(bbcount: int, pc: Optional[int] = None)¶
Deprecated since version 6.4: use
Time
instead.
- exception debugger_extensions.SaveError(filename: pathlib.Path, msg: str)¶
An error occurred while trying to save a recording.
- class debugger_extensions.SigInfo(si_signo: int, si_code: int, from_event_replay: bool)¶
Information about a signal delivered to a program.
This class mirrors the
siginfo_t
C structure (seeman 2 sigaction
), but also contains UDB specific fields.- from_event_replay: bool¶
True
if the signal was replayed from an event that happened during the recording of the program.False
if the signal corresponds to a real signal delivered to the program.This is useful, for instance, to distinguish if a
SIGINT
corresponds the the user pressing CTRL-C while replaying a recording or if the signal was recorded at execution time.
- si_code: int¶
Extra information about the signal whose value depends on the value of
si_signo
.See the
sigaction
man page for details.
- si_signo: int¶
The number of the received signal.
See the
signal
module for details.
- class debugger_extensions.Time(bbcount: int, pc: Optional[int] = None)¶
A time in execution history.
For details on how UDB represents time, see UDB time notation.
- bbcount: int¶
The bbcount for this time.
- Type
int
- pc: int | None = None¶
The PC (program counter) for this time or
None
if the PC is not specified.- Type
int
orNone
- to_string(include_pc: bool = True, extend_pc: bool = False) str ¶
Converts this time into a string suitable for displaying to the user.
This is equivalent to using
str
, unless any argument is specified.- Parameters
include_pc (
bool
) – If true, then the returned string contains the PC, if it’s available, otherwise the PC is omitted.extend_pc (
bool
) – If true, then the PC part of the return values is padded with zeroes to make all the PCs from different times the same width.
- Returns
A string representation of the time.
- Return type
str
- exception debugger_extensions.WrongExecutionModeError(*args: Any, **kwargs: Any)¶
Raised if UDB tries to execute an operation which is not supported in the current execution mode.
This class cannot be instantiated directly, instantiate an appropriate subclass instead. See
NotRecordingError
,NotRunningError
, andNotSupportedWithCoreFile
.
Utilities built around the gdb
module¶
Utility functions built around GDB and the gdb module.
- debugger_extensions.debugger_utils.breakpoints_suspended(normal_breakpoints: bool = True, watchpoints: bool = True) Iterator[None] ¶
Context manager to temporarily disable breakpoints.
The breakpoints which were previously enabled are automatically restored when the context manager block is left.
It is safe to create or delete breakpoints inside the block.
By default, all types of breakpoints, that is, both watchpoints and normal breakpoints, are disabled. See the
normal_breakpoints
andwatchpoints
arguments to change this behaviour.Example:
with debugger_utils.breakpoints_suspended(): # No breakpoints (of any type) here. ... # Previosuly enabled breakpoints restored here.
To disable only normal breakpoints but not watchpoints:
with debugger_utils.breakpoints_suspended(watchpoints=False): # No normal breakpoints here, but watchpoints still enabled. ... # Normal breakpoints restored here. The watchpoints were never affected.
- Parameters
normal_breakpoints (
bool
) – Whether normal breakpoints (both software and hardware) should be disabled or not.watchpoints (
bool
) – Whether watchpoints (all types, including read, write and read/write ones) should be disabled.
- debugger_extensions.debugger_utils.execute_to_string(cmd: str, *, styled: bool = False, from_tty: bool = False) str ¶
Executes
cmd
returning the output (rather than printing it to standard output).This is similar to calling
gdb.execute()
with theto_string
argument set toTrue
but without being affected by command tracing. Seehelp set trace-commands
in UDB for more details on this feature.- Parameters
cmd (
str
) – The command to execute.styled (
bool
) – Whether the output can contain style special characters (called ANSI escape codes) that change how text is displayed by terminals. Unstyled output is easier to process and parse, while style output is suitable for printing to a standard stream.from_tty (
bool
) –Must be
False
.Deprecated since version 6.10: This argument is dangerous so it doesn’t affect the executed command any more. If not false, a warning is produced.
- debugger_extensions.debugger_utils.suspend_breakpoints(normal_breakpoints=True, watchpoints=True) contextlib.AbstractContextManager[None] ¶
Context manager to temporarily disable breakpoints.
See
breakpoints_suspended()
for more details.Deprecated since version 6.10: Use
breakpoints_suspended()
instead.
- debugger_extensions.debugger_utils.temporary_parameter(parameter, temporary_value) Iterator[None] ¶
Context manager that executes its block with the parameter called
parameter
(seegdb.parameter
) temporarily set totemporary_value
.For instance, to temporarily disable pagination and then restore it to its initial value at the end of the block execution, do:
with debugger_utils.temporary_parameter('pagination', False): ...
Controlling input and output¶
Utility functions to deal with I/O in the debugger.
- class debugger_extensions.debugger_io.CollectOutput¶
Context manager that captures all the output produced during the execution of its block. The accumulated output is acessible via the
output
property.The context manager redirects both the output produced by UDB directly and direct writes to
sys.stdout
orsys.stderr
.For instance:
with CollectOutput() as collector: gdb.execute('echo He') print(collector.output) # Will print "He" gdb.execute('echo llo') print(collector.output) # Will print "Hello" print(collector.output) # Will print "Hello"
It’s safe to nest multiple
CollectOutput
instances. The output will be collected only by the most nested instance ofCollectOutput
:with CollectOutput() as outer: gdb.execute('echo Hello ') with CollectOutput() as inner: gdb.execute(r'echo Something else') gdb.execute('echo world') print(outer.output) # Will print "Hello world" print(inner.output) # Will print "Something else"
If you need the output to go to a file, use
RedirectOutput
instead.- property output: str¶
Get the output collected up so far.
It’s safe to access this both within the with block and after the block terminated.
- class debugger_extensions.debugger_io.RedirectOutput(path: str, overwrite: bool = True)¶
Context manager that redirects all the output produced during the execution of its block to a file.
The context manager redirects both the output produced by UDB directly and direct writes to
sys.stdout
orsys.stderr
.For instance:
with RedirectOutput('some_file.txt'): gdb.execute('echo Hello\n')
Will write
Hello\n
tosome_file.txt
.It’s safe to nest multiple
RedirectOutput
instances. The output will be redirected to the file specified by the most nested instance ofRedirectOutput
If you want to redirect the output for later use in your code but you don’t need it to be in a file, use
CollectOutput
instead.
- debugger_extensions.debugger_io.redirect_to_launcher_output() Iterator[None] ¶
Context manager that redirects all the output produced during the execution of its block to the standard output of the
UdbLauncher
.This is useful to discard all the output from a UDB launched through the
UdbLauncher
except for the parts printed inside this context manager.For instance, you could start UDB like this:
launcher = udb_launcher.UdbLauncher() launcher.add_extension('code_to_run_inside_undodb') launcher.run_debugger(output=os.devnull)
This makes all the normal output from UDB be redirected to
/dev/null
. If you have some output you want to preserve coming from the extension running inside UDB, you can do this:with launcher.redirect_to_launcher_output(): print('This will come out instead of ending up in /dev/null!') gdb.execute('echo And this too!\n')
If UDB was not launched through
UdbLauncher
, then the output is not redirected and is printed to the normal standard output.