

.. index:: Lua

*************
Lua scripting
*************

The debugger can be controlled and extended using the `Lua language
<https://www.lua.org/>`_. Scripting allows you to write programs that
execute inside the debugger, from simple batch-like scripts to advanced
plug-ins that add custom commands, listen to internal events, and control
execution.

From a high-level perspective, Lua and the debugger enable various tasks:

* Perform setup tasks to prepare your debug session
* Simplify repetitive tasks
* Run fully automated tests
* Extend functionality; for instance, to introspect the state and behavior
  of an operating system or protocol stack. These commands integrate into
  the existing set and share a command-line interface.

You can choose any automation level, from running the entire session
under script control to providing high-level functionality with commands.


Running a script
================

To get started, this simple Lua program just displays the registers:

.. code-block:: lua

  local db = require('db')

  print(db.consoleCommand('info registers'))


If saved in ``script-name.lua`` (in the current directory), you can run
the script with:

.. code-block:: sh

  (db) source script-name.lua

Debugger functionality is provided in the ``db`` table which is
created before the script is started. To access it, you need to use
``require``. Here we store the debugger table in the local variable
``db``.

.. note::
   Use the ``--eval-command`` (can also be used as ``-e``) to invoke a
   Lua script from the command line and to make it execute automatically
   when the debugger starts. The ``--eval-command`` works with any
   command and can be specified multiple times on the command line.


Lua environments
================

Each time you run a Lua script, a new fresh Lua state is created. This
means you will start out with the standard Lua and debugger libraries
available imported, but not anything else. If you create a global
variable, it will not normally be present the next time you run the
script.

However, if a script provides new debugger functions (e.g., console
commands), the Lua state is saved with the command. Subsequent invocations
of that command reuse the same state, retaining global variables and
closures. This allows commands to operate within their established state
and depend on prior actions within that state, including previous uses of
the same or other commands created by the script.

A Lua plug-in typically registers functions with the debugger for specific
circumstances. These functions always execute in the state in which they
were installed.

It is good practice to provide related functionality (e.g., a command
set and plug-in behavior) in its own script. Multiple plug-ins can be
installed via `source` invocation, allowing each to have its private
shared state while co-existing separately.


Command interpreters
====================

The debugger provides two sets of command interpreters, console
commands and MI commands.

Console commands are intended for humans, provide command completion
when being entered and formatted output that is easy to read.

The Machine Interface (or *MI* for short), was introduced by GDB to
provide a more precise and stable command protocol, intended for
(graphical) debugger front-ends. The GDB MI command set is supported
by the debugger, allowing existing graphical debugger front-ends to be
used.

Many commands can be accessed from either of these command
sets, while some commands are only available in one of them.

The Lua interface allows both command sets to be used. In addition,
adapted MI commands and additional functionality are also provided.


Console commands
================

The ``db`` table allows sending console commands to the debugger.
These commands execute as if typed at the terminal, and their string
results are passed back to Lua.

If you need to process the result beyond displaying or ignoring it, parsing
is required. However, writing such parsers quickly becomes tedious, as the
text output is primarily for display.


MI commands
===========

MI commands offer precise interaction for debugger front-ends, making them
well-suited for Lua scripts. Although commands are string-based, results
are converted to nested Lua tables with basic types (booleans, numbers,
strings).

This significantly simplifies interpreting results from Lua-to-debugger calls.


Adapted MI commands
===================

Adapted MI commands are basically MI commands converted to be a more
natural fit for Lua. This is done in two ways. The actual commands
take arguments like any ordinary function in Lua. A return values is
the value returned or a failure, instead of the MI style result
table hierarchy.


Choosing a command set
======================

In most cases you will probably want to use the adapted MI command set
as it provides the most natural Lua experience.

The console and MI command set may be useful if you have familiarity
with either or prefer the alternative output form provided.


Arrays and Lua
==============

Lua array indices start at 1, unlike C. This mismatch has implications
when working with debugger C expressions from Lua.

To simplify working with C expressions, array results can start at 0 in
Lua, mirroring C behavior. However, the `ipairs` iterator (designed for
Lua's 1-based indexing) will skip the element at index 0.

Shifting the index in expressions is an alternative, but it would likely
be more confusing and error-prone, especially given the context of C
expressions.


Debugger API
============

.. py:function:: db:stepInstruction()

   Single step once at instruction level. This function will quickly
   return an indication of whether it was successful in starting the
   target. Actual progress of execution will be posted as
   notifications

   Corresponding MI instruction is ``-exec-step-instrucion``.
