Debugging programs from the console
Introduction
For terminals that do not support the full KCML Workbench a simple line editor and immediate mode debugger is available.
Once a program has been executed, any run time errors will halt program execution and display the program line with the appropriate error message. The reason for the error is reported with a code and an explanation. Recoverable errors may be trapped with ERROR and ON ERROR statements, or program execution may be transferred to another line and continued with the GOTO and CONTINUE commands, or can be instructed to continue with the next statement with the CONTINUE command. Refer to chapter 21 for a complete list of possible error codes and recovery methods.
Halting program execution
The STOP statement
Program execution can be temporarily halted by pressing the HALT key, by setting a TRAP on a specified line and statement number, subroutine label or variable name, or when a STOP statement is executed, all of which interrupt program flow and return to immediate mode.
The STOP statement can be inserted anywhere within the program, but is best used at places within the program code that should never be executed unless there is a serious bug in the program. For example:
. .
ON count GOTO 1000,2000,3000
STOP "Invalid option"
would display the stop message if the variable count was <1 or >3.
The RUN STOPrun command can be used to resolve the program and STOP before any program lines are executed. This can be useful in checking for resolve time errors such as mismatched DO groups.
The PANIC statement
As an alternative to the STOP statement the PANIC statement may be used to create an ASCII file in the current directory containing a snapshot of the current program state. The user will then be returned back to the native operating system prompt terminating KCML. The panic file contains program state information including the screen contents, login name (UNIX versions only), terminal number, and the output from the LIST RETURN, LIST DIM and LIST DT commands. The file is created in the current working directory, unless the PANICDIR environment variable is set. When the PANIC statement is executed the message:
Unexpected program condition on line lllll of program prg
Dumping program state to file panicpppp
RETURN to resume
Where llll is the program line containing the PANIC statement, prg is the name of the program containing the PANIC statement, and pppp is the UNIX process id number of the currently running KCML task. On DOS versions the file is named PANlllll. Where lllll is a unique number taken from the current date and time.
The STOP PANIC ON statement can be used to instruct KCML to consider all subsequent STOP statements as PANIC statements, this avoids having to change existing code containing STOP statements to include PANIC statements. The STOP PANIC OFFstoppanic statement restore to the original meaning of STOP.
The TRAP command
The TRAP command allows a trap to be set on a specific line number and optionally a specific statement number within the line, or a specific variable or subroutine name. Just before executing a trapped line and statement, variable or subroutine, KCML will stop and display the line. E.g.
TRAP 100,5
TRAP name$
TRAP 'get_next_record
would set a trap on line 100 statement 5, on the variable name$ and on the subroutine 'get_next_record.
TRAP are preserved over a subsequent program LOAD. TRAP’strap are only set for foreground lines, and subroutines unless the reserved word TRAP is preceded with the `@' sign, for example:
@TRAP 100,5
@TRAP 'get_next_record
would set TRAP’s on the same line and subroutine as before but would only halt execution if executed in any global partition. Setting a trap on a variable will stop whenever the variable is executed even if executed in the currently selected global partition.
There is no limit to the number of TRAPs that can be active at any one time. A list of currently active TRAP can be obtained with the LIST TRAP command, for example:
LIST TRAP LINE STAT ---- ---- 100 5 @ 100 5 SUBROUTINE ---------- 'GET_NEXT_RECORD @ 'GET_NEXT_RECORD VARIABLE -------- NAME$
TRAPs are removed by reissuing the original TRAP statement, thus toggling the trap off, for example:
TRAP 100,5
would turn off the trap set in the previous example. All foreground TRAP can be removed with the TRAP OFF command, all global trap can be removed with the @TRAP OFF, or all TRAPs, both foreground and global, can be removed with the TRAP ALL OFF command.
The TRAP command also has a watch point facility allowing optional trailing statements which are executed when a TRAP is reached. For example:
TRAP name$ : IF name$="Steve" THEN STOP
would only stop program execution if the variable name$ was equal to `Steve'. Any number of statements may be used after the TRAP command. GOTO and GOSUB statements can also be used although care should be taken to ensure that program flow is returned to the TRAP statement, this may be difficult if GOTO is used, see table below for some examples of valid TRAP commands.
TRAP 1000 |
Halt the program before the foreground line 1000 is executed. If the TRAP is already set then remove it. |
TRAP 'newsub |
Halt the program before the subroutine 'newsub is executed. If the TRAP is already set then remove it. |
@TRAP 9000,4 |
Halt the program before the global partition line 9000 statement 4 is executed. If the TRAP is already set then remove it. |
TRAP tp$: IF tp$="A" THEN GOSUB 9000:count++ |
If the variable tp$ is executed and it is currently equal to "A" then branch to line 9000. Upon returning or if tp$ not equal to "A", increment the variable count by 1. If the TRAP is already set then remove it. |
TRAP OFF |
Remove all foreground TRAP. |
@TRAP OFF |
Remove all global TRAP. |
TRAP ALL OFF |
Remove all foreground and global TRAP. |
See also:
STOP, TRAP, PANIC, CONTINUE, RUNAnalysing the program and variable status
Once in immediate mode, variables may be examined with the PRINT or LIST DIM commands, the program itself may be listed with the LIST command, or any of the other LIST commands may be used to obtain information about the current contents and state of the program and memory. The $PROG, #LINE, and #STAT functions may be used to find the name of the last program loaded, the number of the line currently being executed and the statement number within the line being executed, respectively. The following summarises the LIST statements useful for debugging programs
Displays the program text currently held in memory in line sequence. Ranges of lines may be displayed by specifying lines numbers after the command. If the `@' sign precedes the reserved word LIST then the LISTing is taken from the currently selected global partition. |
|
Displays all references to given CALLs in a program. If the `@' sign precedes the reserved word LIST then the LISTing is taken from the currently selected global partition. |
|
Displays both common and non-common variables and their contents in the order in which they were declared, except that all common variables precede the non-common variables. |
|
Displays the current contents of the device and device equivalence tables. |
|
Displays all local KCML environment variables set by the ENV( function. |
|
Lists from the first line of the requested subroutine. |
|
Lists information about the currently executing program. Information includes the currently executing line and statement number, the last programs loaded, and the name of the currently selected global partition, if any, and the contents of the return stack. If executed within a subroutine containing local variables then the variable names and contents of any non unique local variables are also shown. |
|
Lists either a specified local variable or all currently defined local variables. |
|
Displays a summary of where memory has been allocated. |
|
Searches for instances of the specified text in the program currently being held in memory. If the ‘@’ sign precedes the reserved word LIST then the LISTing is taken from the currently selected global partition. |
|
LIST P performs the same function as LIST T except that some pattern matching characters similar to those used by UNIX editors can be used. If the `@' sign precedes the reserved word LIST then the LISTing is taken from the currently selected global partition. |
|
Lists all currently active TRAP statements. |
|
Lists all of the available C user written routines and a summary of their expected arguments. |
|
Lists instances of a variable in a program. If the `@' sign precedes the reserved word LIST then the LISTing is taken from the currently selected global partition. |
|
Lists all references to the specified line within the program currently in memory. If the `@' sign precedes the reserved word LIST then the LISTing is taken from the currently selected global partition. |
|
Lists all references to the specified defined subroutine in a program. If the `@' sign precedes the reserved word LIST then the LISTing is taken from the currently selected global partition. |
|
Lists the line numbers of lines containing syntax errors. |
|
Lists all variables which appear only once in the current program. If the `@' sign precedes the reserved word LIST then the LISTing is taken from the currently selected global partition. |
Continuing a halted program
As long as no program lines are created or modified, the execution of a program can be continued with one of the CONTINUE, CONTINUE LOAD, CONTINUE LOOP, CONTINUE NEXT or CONTINUE RETURN commands or each subsequent statement may be stepped one at a time by pressing, if enabled, the HALT/STEPhalt key.
The CONTINUE command will resume execution of the program. To CONTINUE the program at a different line number the GOTO statement may be used. Jumping in and out of loops and subroutines is allowed but will eventually generate an error as the next RETURN, NEXT, WEND or UNTIL statement may not be in the return stack.
CONTINUE LOAD will restart the program and stop immediately before the next LOAD statement.
CONTINUE LOOP will restart the program and stop immediately before the last iteration which would complete the current WHILE ... WEND or REPEAT ... UNTIL loop.
CONTINUE NEXT will restart the program and stop immediately before the last iteration which would complete the current FOR .. NEXT loop.
CONTINUE RETURN will restart the program and stop it again immediately after the next RETURN statement associated with the most recent GOSUB or GOSUB' statement.
The RUN command followed by a line number will resolve the program, and begin execution at the specified line; non-common variables are not cleared from memory and all variables retain their current values.
Tracing program flow
The TRACE statement produces a trace of program operations. Trace mode may be turned on when the TRACE statement is either executed from within a program or Immediate mode. Trace mode is turned off with the TRACE OFF command.
By specifying two line numbers TRACE output will appear only when the program is executing between the two specified line numbers. While executing outside this range no tracing occurs. While this form of TRACE is active, the HALT key will not stop execution until the program is executing a line outside the specified range. Thus programs can be stepped through but standard subroutines in an overlay may be skipped.
Trace reports on GOTO, GOSUB and GOSUB' branches, RETURN statements, NEXT statements, WHILE ... WENDwhile and REPEAT ... UNTILrepeat loops, SELECT CASE statements, and TRAP executed code.
The SELECT TRACE statement allows the output from the TRACE command to be written to a native operating system file or device, e.g.
TRACE 1000,5000 SELECT TRACE "/tmp/TRACEFILE"
would copy the output from the TRACE command into the file `/tmp/TRACEFILE'. This allows the program to be TRACEd, without effecting the screen display.