Contents Previous Next Index
|
16 Testing, Debugging, and Efficiency
|
|
New programs, whether developed in Maple or any other language, sometimes work incorrectly. Problems that occur when a program is run can be caused by syntax errors introduced during implementation, logic errors in the design of the algorithm, or errors in the translation of an algorithm's description into code. Many errors can be subtle and hard to find by visually inspecting your program. Maple provides error detection commands and a debugger to help you find these errors.
Maple has several commands to help you find errors in procedures. Among these are commands to trace procedure execution, check assertions, raise exceptions and trap errors, and verify procedure semantics and syntax.
Additionally, the Maple debugger lets you stop in an executing Maple procedure, inspect and modify the values of local and global variables, and continue the execution process, either to completion, or one statement or block at a time. You can stop the execution process when Maple reaches a particular statement, when it assigns a value to a specified local or global variable, or when a specified error occurs. This facility lets you investigate the inner workings of a program.
Even when a program is working correctly, you may want to analyze its performance to try to improve its efficiency. Maple commands are available to analyze the time and memory consumption involved in running a program.
|
16.1 In This Chapter
|
|
•
|
Using the Maple debugger
|
•
|
Detailed debugger information
|
•
|
Additional commands for error detection
|
•
|
Measuring and improving program efficiency
|
|
|
16.2 The Maple Debugger: A Tutorial Example
|
|
The Maple debugger is a tool that you can use to detect errors in your procedures. Using this facility, you can follow the step-by-step execution of your code to determine why it is not returning the results that you expect.
This section illustrates how to use the Maple debugger as a tool for debugging a Maple procedure. The debugger commands are introduced and described as they are applied. For more information about the debugger commands, see Maple Debugger Commands.
You can use the command-line Maple debugger or you can use the interactive Maple debugger available in the standard interface.
|
Figure 16.1: The Maple Debugger in the Standard Interface
|
|
|
In the standard interface, the interactive Maple debugger is opened automatically by Maple when a breakpoint or watchpoint is encountered during the execution of a program. An interactive debugger window is displayed, which contains the following components:
•
|
a main text box that displays a procedure name and the debugger output
|
•
|
a field for entering commands and an associated Execute button
|
•
|
buttons that perform common debugging functions
|
While the interactive debugger has a different user interface, it otherwise functions identically to the command-line Maple debugger. For more information, refer to the InteractiveDebugger help page.
This section introduces various debugger commands. To present and describe all of the options available for these commands, the command-line debugger will be used instead of the interactive debugger. Note that the Common Debugger Commands buttons in the interactive debugger always implement the corresponding commands with their default options. To run a debugger command with non-default options in the interactive debugger, enter the command and options in the Enter a debugger command: field and click the Execute button.
|
Example
|
|
Consider the following procedure, sieve, which is used as a case study. It implements the Sieve of Eratosthenes: given a parameter n, return a count of the prime numbers less than or equal to n. To debug the sieve procedure, breakpoints and watchpoints will be used to stop the the execution of the procedure at selected points or on selected events.
>
|
sieve := proc(n::integer)
local i, k, flags, count,twicei;
count := 0;
for i from 2 to n do
flags[i] := true;
end do;
for i from 2 to n do
if flags[i] then
twicei := 2*i;
for k from twicei by i to n do
flags[k] = false;
end do;
count := count+l;
end if;
end do;
count;
end proc:
|
|
|
Numbering the Procedure Statements I
|
|
To use the Maple debugger, you can enter several debugger commands. Many of these debugger commands refer to statements in the procedures that you are debugging. Statement numbers allow such references. The showstat command displays a Maple procedure along with numbers preceding each line that begins a new statement.
sieve := proc(n::integer)
local i, k, flags, count, twicei;
1 count := 0;
2 for i from 2 to n do
3 flags[i] := true
end do;
4 for i from 2 to n do
5 if flags[i] then
6 twicei := 2*i;
7 for k from twicei by i to n do
8 flags[k] = false
end do;
9 count := count+l
end if
end do;
10 count
end proc
| |
Note: The numbers preceding each line differ from line numbers that may be displayed in a text editor. For example, keywords that end a statement (such as end do and end if) are not considered separate Maple commands and are therefore not numbered.
|
|
Invoking the Debugger I
|
|
To invoke the Maple debugger, execute a procedure and then stop the execution process within the procedure. To execute a Maple procedure, call it by using a Maple command at the top level or call it from another procedure. The simplest way to stop the execution process is to set a breakpoint in the procedure.
|
|
Setting a Breakpoint
|
|
Use the stopat command to set a breakpoint in the sieve procedure.
| (1) |
This command sets a breakpoint before the first statement in the procedure sieve. When you subsequently execute the sieve procedure, Maple stops before executing the first statement and waits for you to provide instructions on what to do next. When the execution process stops, the debugger prompt is displayed (DBG>).
Note: If a procedure has a remember table or a cache table, you may have to run the restart command before running a second or subsequent stopat command. For more information about remember tables and cache tables, see The remember, cache, and system Options or refer to the remember or CacheCommand help pages.
In the following example, the sieve procedure is called.
sieve:
1* count := 0;
DBG>
|
|
|
Several pieces of information are displayed after the debugger prompt.
•
|
The previously computed result. This particular execution process stopped at the first statement before making any computations, so no result appears.
|
•
|
The name of the procedure in which the execution process has stopped (sieve).
|
•
|
The execution process stopped before statement number 1. An asterisk (*) follows this statement number to indicate that a breakpoint was set before the statement.
|
At the debugger prompt, you can evaluate Maple expressions and call debugger commands. Maple evaluates expressions in the context of the stopped procedure. You have access to the same procedure parameters, and local, global, and environment variables as the stopped procedure. For example, since the sieve procedure was called with parameter value 10, the formal parameter n has the value 10.
DBG> n
10
sieve:
1* count := 0;
|
|
|
For each expression that Maple evaluates,
•
|
the result of the expression is displayed; if there is no result, the most recent previous result is displayed (this output can be suppressed by using a colon to terminate the command entered at the DBG> prompt)
|
•
|
the name of the stopped procedure
|
•
|
the statement number where the procedure stopped followed by the statement, and
|
Note: To remove a breakpoint from a procedure, use the unstopat command.
|
|
Controlling the Execution of a Procedure during Debugging I
|
|
Debugger commands control how the procedure is executed once the debugger is started. Some commonly used debugger commands are next, step, into, list, outfrom, and cont.
The next command runs the next statement at the current nesting level. After the statement is run, control is returned to the debugger. If the statement is a control structure (for example, an if statement or a loop), the debugger runs any statements within the control structure that it would normally run. It stops the execution process before the next statement after the control structure. Similarly, if the statement contains calls to procedures, the debugger executes these procedure calls in their entirety before the execution process stops.
DBG> next
0
sieve:
2 for i from 2 to n do
...
end do;
DBG>
|
|
|
The 0 in the first line of the output represents the result of the statement that was run--that is, the result of count := 0. A "*" does not appear next to the statement number because there is no breakpoint set immediately before statement 2. The debugger does not show the body of the for loop, which itself consists of statements with their own statement numbers, unless the execution process actually stops within its body. Maple represents the body of compound statements by ellipses (...).
Running the next command again results in the following output.
DBG> next
true
sieve:
4 for i from 2 to n do
...
end do;
DBG>
|
|
|
The execution process now stops before statement 4. Statement 3 (the body of the previous for loop) is at a deeper nesting level. The loop is executed n-1 times. The debugger displays the last result computed in the loop (the assignment of the value true to flags[10]).
Tip: If you want to repeat the previous debugger command, as shown in the second next command above, you can press Enter at the DBG> prompt. You can also view your recent command history using the up and down arrow keys on your keyboard.
To step into a nested control structure (such as an if statement or for loop) or a procedure call, use the step debugger command.
DBG> step
true
sieve:
5 if flags[i] then
...
end if
DBG> step
true
sieve:
6 twicei := 2*i;
DBG>
|
|
|
If you use the step debugger command when the next statement to run is not a deeper structured statement or procedure call, it has the same effect as the next debugger command.
DBG> step
4
sieve:
7 for k from twicei by i to n do
...
end do;
DBG>
|
|
|
At any time during the debugging process, you can use the showstat debugger command to display the current status of the debugging process.
DBG> showstat
sieve := proc(n::integer)
local i, k, flags, count, twicei;
1* count := 0;
2 for i from 2 to n do
3 flags[i] := true
end do;
4 for i from 2 to n do
5 if flags[i] then
6 twicei := 2*i;
7 ! for k from twicei by i to n do
8 flags[k] = false
end do;
9 count := count+l
end if
end do;
10 count
end proc
DBG>
|
|
|
Maple displays a debugger prompt to indicate that you are still working within the Maple debugger. The asterisk (*) indicates the unconditional breakpoint. An exclamation point (!) that follows a statement number (see line 7) indicates the statement at which the procedure is stopped.
To continue the debugging process, run another debugger command. For example, you can use into or step to enter the innermost loop.
The behavior of the into debugger command is between that of the next and step commands. The execution process stops at the next statement in the current procedure independent of whether it is at the current nesting level or in the body of a control structure (an if statement or a loop). That is, the into command steps into nested statements, but not procedure calls. It executes called procedures completely and then stops.
DBG> into
4
sieve:
8 flags[k] = false
DBG>
|
|
|
A debugger command that is related to showstat is the list command. It displays the previous five statements, the current statement, and the next statement to indicate where the procedure has stopped.
DBG> list
sieve := proc(n::integer)
local i, k, flags, count, twicei;
...
3 flags[i] := true
end do;
4 for i from 2 to n do
5 if flags[i] then
6 twicei := 2*i;
7 for k from twicei by i to n do
8 ! flags[k] = false
end do;
9 count := count+l
end if
end do;
...
end proc
DBG>
|
|
|
You can use the outfrom debugger command to finish the execution process at the current nesting level or at a deeper level. Execution of the procedure is stopped once a statement at a shallower nesting level is reached, that is, after a loop terminates, a branch of an if statement executes, or the current procedure call returns.
DBG> outfrom
true = false
sieve:
9 count := count+l
DBG> outfrom
l
sieve:
5 if flags[i] then
...
end if
DBG>
|
|
|
The cont debugger command continues the execution process until either the procedure stops normally or encounters another breakpoint.
| (2) |
The procedure does not give the expected output. Although you may find the reason obvious from the previous debugger command examples, in other cases, it may not be easy to find procedure errors. Therefore, continue to use the debugger. First, use the unstopat command to remove the breakpoint from the sieve procedure.
| (3) |
|
|
Invoking the Debugger II
|
|
The procedure sieve maintains the changing result in the variable count. Therefore, a logical place to look during debugging is wherever Maple modifies count. The easiest way to do this is by using a watchpoint, which starts the debugger whenever Maple modifies a variable that you identify.
|
|
Setting a Watchpoint
|
|
Use the stopwhen command to set watchpoints. In this case, the execution process will stop whenever Maple modifies the variable count in the procedure sieve.
>
|
stopwhen([sieve,count]);
|
| (4) |
The stopwhen command returns a list of all the currently watched variables (that is, the variables that you provided to the stopwhen command).
Execute the sieve procedure again.
count := 0
sieve:
2 for i from 2 to n do
...
end do;
DBG>
|
|
|
The execution process stops because Maple modified count and the debugger displays the assignment statement count := 0. Similar to breakpoints, the debugger then displays the name of the procedure and the next statement to be run in the procedure. Note that the execution process stops after Maple assigns a value to count.
This first assignment to count is correct. Use the cont debugger command to continue the execution process.
DBG> cont
count := l
sieve:
5 if flags[i] then
...
end if
DBG>
|
|
|
At first glance, this may look correct. Assume that the output is correct and continue the execution process.
DBG> cont
count := 2*l
sieve:
5 if flags[i] then
...
end if
DBG>
|
|
|
This output appears to be incorrect because Maple should have simplified 2*1. Note that it printed 2*l (two times the letter l) instead. By examining the source text for the procedure, you can see that the letter "l" was entered instead of the number "1". Since the source of the error has been discovered, you can stop the procedure. Use the quit debugger command to stop the debugger, and then use the unstopwhen command to remove the watchpoint from the procedure.
| (5) |
After correcting the source code for sieve, run the restart command, re-execute that source code (for example, read it into your command-line session or re-execute that code region in your worksheet), and execute the procedure again.
>
|
sieve := proc(n::integer)
local i, k, flags, count,twicei;
count := 0;
for i from 2 to n do
flags[i] := true;
end do;
for i from 2 to n do
if flags[i] then
twicei := 2*i;
for k from twicei by i to n do
flags[k] = false;
end do;
count := count+1;
end if;
end do;
count;
end proc:
|
| (6) |
This result is still incorrect. There are four primes less than 10, namely 2, 3, 5, and 7. Therefore, start the debugger once more, stepping into the innermost parts of the procedure to investigate. Since you do not want to start executing the procedure from the start, set the breakpoint at statement 6.
| (7) |
true
sieve:
6* twicei := 2*i;
DBG> step
4
sieve:
7 for k from twicei by i to n do
...
end do;
DBG> step
4
sieve:
8 flags[k] = false
DBG> step
true = false
sieve:
8 flags[k] = false
DBG>
|
|
|
The last step reveals the error. The previously computed result should have been false (from the assignment of flags[k] to the value false), but instead the value true = false was returned. An equation was used instead of an assignment. Therefore, Maple did not set flags[k] to false.
Once again, stop the debugger and correct the source text.
The following code represents the corrected procedure.
>
|
sieve := proc(n::integer)
local i, k, flags, count,twicei;
count := 0;
for i from 2 to n do
flags[i] := true
end do;
for i from 2 to n do
if flags[i] then
twicei := 2*i;
for k from twicei by i to n do
flags[k] := false;
end do;
count := count+1;
end if;
end do;
count;
end proc:
|
Execute the sieve procedure again to test the corrections.
| (8) |
The sieve procedure returns the correct result.
|
|
|
16.3 Maple Debugger Commands
|
|
This section provides additional details about the commands used in The Maple Debugger: A Tutorial Example and a description of other debugger commands.
|
Numbering the Procedure Statements II
|
|
The showstat command has the following syntax. The procedureName parameter is optional.
showstat( procedureName );
|
|
|
If showstat is called with no arguments, all procedures that contain breakpoints are displayed.
You can also use the showstat command to display a single statement or a range of statements by using the following syntax.
showstat( procedureName, number );
|
showstat( procedureName, range );
|
|
|
In these cases, the statements that are not displayed are represented by ellipses (...). The procedure name, its parameters, and its local and global variables are always displayed.
>
|
f := proc(x)
if x <= 2 then
print(x);
end if;
print(-x);
end proc:
|
f := proc(x)
...
2 print(x)
end if;
3 print(-x)
end proc
| |
|
|
Invoking the Debugger III
|
|
This section provides additional information about breakpoints and watchpoints.
|
Setting Breakpoints
|
|
The stopat command has the following syntax, where procedureName is the name of the procedure in which to set the breakpoint, statementNumber is the line number of the statement in the procedure before which the breakpoint is set, and condition is a Boolean expression which must be true to stop the execution process. The statementNumber and condition arguments are optional.
stopat( procedureName, statementNumber, condition );
|
|
|
The condition argument can refer to any global variable, local variable, or parameter of the procedure. These conditional breakpoints are indicated by a question mark (?) if the showstat command is used to display the procedure.
Since the stopat command sets the breakpoint before the specified statement, when Maple encounters a breakpoint, the execution process stops and Maple starts the debugger before the statement.
Note: This means that you cannot set a breakpoint after the last statement in a statement sequence--that is, at the end of a loop body, an if statement body, or a procedure.
If two identical procedures exist, depending on how you created them, they may share breakpoints. If you entered the procedures individually, with identical procedure bodies, they do not share breakpoints. If you created a procedure by assigning it to the body of another procedure, their breakpoints are shared.
>
|
f := proc(x) x^2 end proc:
g := proc(x) x^2 end proc:
h := op(g):
stopat(g);
|
| (9) |
g := proc(x)
1* x^2
end proc
h := proc(x)
1* x^2
end proc
| |
|
|
Removing Breakpoints
|
|
The unstopat command has the following syntax, where procedureName is the name of the procedure that contains the breakpoint, and statementNumber is the line number of the statement where the breakpoint is set. The statementNumber parameter is optional.
unstopat( procedureName, statementNumber );
|
|
|
If statementNumber is omitted in the call to unstopat, all breakpoints in the procedure procedureName are cleared.
|
|
Setting Explicit Breakpoints
|
|
You can set an explicit breakpoint by inserting a call to the DEBUG command in the source text of a procedure. The DEBUG command has the following syntax. The argument parameter is optional.
If no argument is included in the DEBUG command, execution in the procedure stops at the statement following the location of the DEBUG command, and then the debugger is started.
Note: The showstat command does not mark explicit breakpoints with an "*" or a "?".
>
|
f := proc(x,y) local a;
a:=x^2;
DEBUG();
a:=y^2;
end proc:
|
f := proc(x, y)
local a;
1 a := x^2;
2 DEBUG();
3 a := y^2
end proc
| |
4
f:
3 a := y^2
DBG> quit
Interrupted
|
|
|
If the argument of the DEBUG command is a Boolean expression, the execution process stops only if the Boolean expression evaluates to true. If the Boolean expression evaluates to false or FAIL, the DEBUG command is ignored.
>
|
f := proc(x,y) local a;
a:=x^2;
DEBUG(a<1);
a:=y^2;
DEBUG(a>1);
print(a);
end proc:
|
9
f:
5 print(a)
DBG> quit
Interrupted
|
|
|
If the argument of the DEBUG command is a value other than a Boolean expression, the debugger prints the value of the argument (instead of the last result) when the execution process stops at the following statement.
>
|
f := proc(x)
x^2;
DEBUG("This is my breakpoint. The current value of x is:", x);
x^3;
end proc:
|
"This is my breakpoint. The current value of x is:",
2
f:
3 x^3
DBG>
|
|
|
|
|
Removing Explicit Breakpoints
|
|
The unstopat command cannot remove explicit breakpoints. You must remove breakpoints that were set by using DEBUG by editing the source text for the procedure.
DBG> unstopat
[f]
f:
3 x^3
DBG> showstat
f := proc(x)
1 x^2;
2 DEBUG("This is my breakpoint. The current value of x is:", x);
3 ! x^3
end proc
DBG> quit
Interrupted
|
|
|
Note: If you display the contents of a procedure by using the print command (or lprint) and the procedure contains a breakpoint that was set by using stopat, the breakpoint appears as a call to DEBUG.
>
|
f := proc(x) x^2 end proc:
|
| (10) |
| (11) |
|
|
Setting Watchpoints
|
|
The stopwhen command can take the following forms.
stopwhen( globalVariableName );
|
stopwhen( [procedureName, variableName] );
|
|
|
The first form specifies that the debugger should be started when the global variable globalVariableName is changed. Maple environment variables, such as Digits, can also be monitored by using this method.
| (12) |
The second form starts the debugger when the (local or global) variable variableName is changed in the procedure procedureName.
When any form of stopwhen is called, Maple returns a list of the current watchpoints.
The execution process stops after Maple assigns a value to the watched variable. The debugger displays an assignment statement instead of the last computed result (which would otherwise be the right-hand side of the assignment statement).
|
|
Clearing Watchpoints
|
|
The syntax to call unstopwhen is the same as that for stopwhen. Similar to the stopwhen command, the unstopwhen command returns a list of all (remaining) watchpoints.
If no arguments are included in the call to unstopwhen, then all watchpoints are cleared.
|
|
Setting Watchpoints on Specified Errors
|
|
You can use an error watchpoint to start the debugger when Maple returns a specified error message. When a watched error occurs, the procedure stops executing and the debugger displays the statement in which the error occurred.
Error watchpoints are set by using the stoperror command. The stoperror command has the following syntax
stoperror( "errorMessage" );
|
|
|
where errorMessage is a string or a symbol that represents the error message returned from the evaluation of a Maple expression. If the argument is a string, the debugger will be started when an error for which the given string is a prefix is encountered. A list of the current error watchpoints is returned.
If no argument is entered in the call to stoperror, the list of current (error) watchpoints is returned.
| (13) |
>
|
stoperror( "numeric exception: division by zero" );
|
| (14) |
| (15) |
If the special name `all` is used instead of a specific error message as the parameter to the stoperror command, a procedure stops executing when any error that would not be trapped occurs.
Errors trapped by an error trapping construct (try...catch statement) do not generate an error message. Therefore, the stoperror command cannot be used to catch them. For more information about the try...catch structure, see Trapping Errors. If the special name `traperror` is used instead of a specific error message as the parameter to the stoperror command, a procedure stops executing when any error that is trapped occurs. If the errorMessage parameter is entered in the form traperror["message"] to stoperror, the debugger starts only if the error specified by "message" is trapped.
When a procedure stops executing because of an error which causes an exception, continued execution is not possible. Any of the execution control commands, such as next or step (see Controlling the Execution of a Procedure during Debugging I and Controlling the Execution of a Procedure during Debugging II), process the error as if the debugger had not intervened. For example, consider the following two procedures. The first procedure, f, calculates 1/x. The other procedure, g, calls f but traps the "division by zero" error that occurs when x = 0.
>
|
f := proc(x) 1/x end proc:
g := proc(x) local r;
try
f(x);
catch:
infinity;
end try;
end proc:
|
If procedure g is executed at x=9, the reciprocal is returned.
| (16) |
At x=0, as expected, a value of infinity is returned.
| (17) |
The stoperror command stops the execution process when you call f directly.
>
|
stoperror("numeric exception: division by zero");
|
| (18) |
Error, numeric exception: division by zero
f:
1 1/x
DBG> cont
Error, (in f) numeric exception: division by zero
|
|
|
The call to f from g is within a try...catch statement, so the "division by zero" error does not start the debugger.
| (19) |
Instead, try using the stoperror(traperror) command.
>
|
unstoperror( "numeric exception: division by zero" );
|
| (20) |
>
|
stoperror( `traperror` );
|
| (21) |
This time, Maple does not stop at the error in f.
However, Maple starts the debugger when the trapped error occurs.
Error, numeric exception: division by zero
f:
1 1/x
DBG> step
Error, numeric exception: division by zero
g:
3 infinity
DBG> step
|
|
|
| (22) |
In the case that a particular error message is specified in the form traperror["message"], the debugger is started only if the error specified by "message" is trapped.
|
|
Clearing Watchpoints on Specified Errors
|
|
Error watchpoints are cleared by using the top-level unstoperror command. The syntax to call the unstoperror command is the same as for the stoperror command. Like the stoperror command, the unstoperror command returns a list of all (remaining) error watchpoints.
If no argument is included in the call to unstoperror, all error watchpoints are cleared.
| (23) |
|
|
|
Controlling the Execution of a Procedure during Debugging II
|
|
After stopping the execution of a procedure and starting the debugger, you can examine the values of variables or perform other experiments (see the following section, Changing the State of a Procedure during Debugging). After you have examined the state of the procedure, you can continue the execution process by using several different debugger commands.
The most commonly used debugger commands are into, next, step, cont, outfrom, return, and quit.
The return debugger command causes execution of the currently active procedure call to complete. The execution process stops at the first statement after the current procedure.
The other commands are described in the tutorial in The Maple Debugger: A Tutorial Example. For more information on these and other debugger commands, refer to the debugger help page.
|
|
Changing the State of a Procedure during Debugging
|
|
When a breakpoint or watchpoint stops the execution of a procedure, the Maple debugger is started. In the debugger mode, you can examine the state of the global variables, local variables, and parameters of the stopped procedure. You can also determine where the execution process stopped, evaluate expressions, and examine procedures.
While in the debugger mode, you can evaluate any Maple expression and perform assignments to local and global variables. To evaluate an expression, enter the expression at the debugger prompt. To perform assignments to variables, use the standard Maple assignment statement.
>
|
f := proc(x) x^2 end proc:
|
| (24) |
f:
1* x^2
DBG> sin(3.0);
.1411200081
f:
1* x^2
DBG> cont
|
|
|
| (25) |
The debugger evaluates any variable names that you use in the expression in the context of the stopped procedure. Names of parameters or local variables evaluate to their current values in the procedure. Names of global variables evaluate to their current values. Environment variables, such as Digits, evaluate to their values in the stopped procedure's environment.
If an expression corresponds to a debugger command (for example, your procedure has a local variable named step), you can still evaluate it by enclosing it in parentheses.
>
|
f := proc(step) local i;
for i to 10 by step do
i^2
end do;
end proc:
|
| (26) |
f:
2* i^2
DBG> step
1
f:
2* i^2
DBG> (step)
3
f:
2* i^2
DBG> quit
Interrupted
|
|
|
When the execution process is stopped, you can modify local and global variables by using the assignment operator (:=). The following example sets a breakpoint in the loop only when the index variable is equal to 5.
>
|
sumn := proc(n) local i, sum;
sum := 0;
for i to n do
sum := sum + i
end do;
end proc:
|
sumn := proc(n)
local i, sum;
1 sum := 0;
2 for i to n do
3 sum := sum+i
end do
end proc
| |
| (27) |
Reset the index to 3 so that the breakpoint is encountered again.
DBG> i := 3
sumn:
3? sum := sum+i
DBG> cont
17
sumn:
3? sum := sum+i
DBG> cont
|
|
|
| (28) |
Maple has added the numbers 1, 2, 3, 4, 3, and 4 and returned 17 as the result. By continuing the execution of the procedure, the numbers 5, 6, 7, 8, 9, and 10 are added and 62 is returned as the result.
|
|
Examining the State of a Procedure during Debugging
|
|
You can use two debugger commands to return information about the state of the procedure execution. The list debugger command shows you the location where the execution process stopped within the procedure and the where debugger command shows you the stack of procedure activations.
The list debugger command has the following syntax.
list procedureName statementNumber[..statNumber]
|
|
|
The list debugger command is similar to the showstat command, except that you do not need to specify arguments. If no arguments are included in the call to list, only the five previous statements, the current statement, and the next statement to be executed are displayed. This provides some context in the stopped procedure. In other words, it indicates the static position where the execution process stopped.
The where debugger command shows you the stack of procedure activations. Starting from the top level, it shows you the statement that is executing and the parameters it passed to the called procedure. The where debugger command repeats this for each level of procedure call until it reaches the current statement in the current procedure. In other words, it indicates the dynamic position where execution stopped. The where command has the following syntax.
| | | |