When use of the debugger is enabled and an error occurs, Magma will break
into the command-line debugger. The syntax of the debugger is modelled on the
GNU GDB debugger for C programs, and supports the following commands
(acceptable abbreviations for the commands are given in parentheses):
- backtrace (bt) Print out the stack of function and procedure
calls, from the top level to the point at which the error occurred. Each line
i this trace gives a single frame, which consists of the
function/procedure that was called, as well as all local variable definitions
for that function. Each frame is numbered so that it can be referenced in
other debugger commands.
- frame (f) n Change the current frame to the frame numbered
n (the list of frames can be obtained using the backtrace command).
The current frame is used by other debugger commands, such as print, to
determine the context within which expressions should be evaluated. The
default current frame is the top-most frame.
- list (l) [n] Print a source code listing for the current
context (the context is set by the frame command). If n is specified,
then the list command will print n lines of source code; the default
value is 10.
- print (p) expr Evaluate the expression expr in the current
context (the context is set by the frame command). The print
command has semantics identical to evaluating the expression eval
"expr" at the current point in the program.
- identifiers (id) Print a list of the assigned identifiers in
the current context (the context is set by the frame command). The
identifiers command is equivalent to invoking the ShowIdentifiers
intrinsic at the current point in the program.
- help (h) Print brief help on usage.
- quit (q) Quit the debugger and return to the Magma session.
We now give a sample session in the debugger. In the following, we have
written a function to evaluate f(n) = Σ
i=1n 1 / n, but have in our
implementation we have accidentally included the evaluation of the term at n =
0.
> function f(n)
> if n ge 0 then
> return 1.0 / n + f(n - 1);
> else
> return 1.0 / n;
> end if;
> end function;
>
> SetDebugOnError(true);
> f(3);
f(
n: 3
)
f(
n: 2
)
f(
n: 1
)
f(
n: 0
)
>> return 1.0 / n + f(n - 1);
^
Runtime error in '/': Division by zero
debug> p n
0
debug> p 1.0 / (n + 1)
1.00000000000000000000000000000
debug> bt
#0 *f(
n: 0
) at <main>:1
#1 f(
n: 1
) at <main>:1
#2 f(
n: 2
) at <main>:1
#3 f(
n: 3
) at <main>:1
debug> f 1
debug> p n
1
debug> p 1.0 / n
1.00000000000000000000000000000
V2.28, 13 July 2023