PowerAda Manipulating Debugger and Program Variables
The debugger variables facility allows you to construct debugger command lines using variable names to replace frequently used strings. There are several commands associated with this facility: DECLARE, UNDECLARE, IMPORT, SHOW DEBUGGER, :=, ?, TRACK, and UNTRACK. := and ? can be used to manipulate program as well as debugger variables.
You create debugger variables by using the DECLARE command, or by invoking a macro that has parameters or local variables. Macro variables are automatically removed when the macro finishes running; you can delete declared variables using the UNDECLARE command. The SHOW DEBUGGER command shows you the value of all debugger variables. TRACK and UNTRACK let you specify which variables you want to monitor during execution.
Debugger variables can contain numeric values, or strings of unlimited length. You can end a line with a line-continuation character to extend the strings beyond one line:
declare long_variable long_variable := "This is an example of\ splitting a command over two lines"
When first created, declared variables and macro local variables contain the null string, while macro parameters contain the values passed in the macro invocation.
The value of debugger variables can be examined and changed in the same way as can program variables, using the "?" and ":=" commands. If a debugger variable and a program variable have the same name, the "?" and ":=" commands refer to the debugger variable; you can fully qualify the name to refer to the program variable. Only numeric literals, string literals, or other debugger variables can be assigned to debugger variables. Debugger variables can be assigned to program variables, provided the program variable is a string of the same length as the value in the debugger variable.
To use the value of a debugger variable in a command line, include the name of the variable, preceded by the variable reference indicator, in the line. For example, if the debugger variable NUMBER contains the text "17", all of the following commands are valid. The variable reference indicator is "$".
source $number source $number,sec/some_package break some_package.display($number):entry count $number
Multiple levels of indirection can be made by repeating the variable reference indicator. For example, suppose the debugger variable NUM_2 contained the text number.
The following commands would be equivalent to the ones in the previous example:
source $$num_2 source $$num_2,sec/some_package break some_package.display($$num_2):entry count $number
A debugger variable is used in one of several ways, depending on when it is evaluated.
A debugger variable in a command is evaluated immediately after the command is entered if the variable is specified by its name, or by its name preceded by the immediate-substitution symbol. This symbol defaults to a value of "!".
Debug 5> declare tries Debug 6> tries := 10 Debug 8> break 35 when misses = !tries -- "misses" and "hits" are program variables Debug 9> tries = misses + hits tries => 32 Debug 10> 6 -- repeat command 6 Debug 11> 9 -- repeat command 9 tries => 10
As shown in the example, you can use the immediate-substitution symbol to repeat previous commands:
!10 1,sec/some_package -- !10 => break !10 sorter.sort:entry un!10 sorter.sort:entry
The HISTORY command displays the numbers of previous commands (See "Recalling Debugger Commands: HISTORY" for more information).
If you specify a variable with its name preceded by the delayed-substitution symbol, the debugger variable in the command will be evaluated only when that command is executed. The delayed-substitution symbol defaults to a value of "$". For simple commands, the difference between immediate and delayed substitution may not be obvious:
declare location location := "sec/sorter.sort:entry" break !location count 4 break $location count 17 -- $location works the same as !location
In a macro or a structured statement, delayed-substitution debugger variables are not evaluated until the macro or statement is executed, as shown in this example:
Debug 1> declare strokes Debug 2> strokes := 5 Debug 3> ? strokes strokes => 5 Debug 4> begin 1 begin Debug 5> strokes := 7 1 begin Debug 6> source !strokes 1 begin Debug 7> source $strokes 1 begin Debug 8> end 5: stuff :sorter.int_array(1..15); -- !strokes 7: BEGIN -- $strokes Debug 9> history 1 declare strokes 2 strokes := 5 3 ? strokes 4 begin 5 strokes := 7 6 source 5 7 source $strokes 8 end
On line 6 above,
!strokes was evaluated immediately to the value of 5, and on line 7,
$strokes was not evaluated until after the
end statement on line 8, when the variable strokes had the value 7.
A direct variable reference includes the variable name and the delayed-substitution symbol:
declare number number := 17 source $number -- $number => 17 source $number,sec/some_package break some_package.display($number):entry count $number
An indirect variable reference includes a variable name, whose value can be another variable, and two delayed-substitution symbols:
declare variable variable := "number" source $$variable -- $$variable => $number => 17 source $$variable,sec/some_package break some_package.display($$variable):entry count $number
When using an indirect reference, the value of a variable can be another variable. Ultimately, in a chain of indirect references, the last variable has a value that is not a variable:
-- The DECLARE line declares the variables used below -- Debug 18> declare d1, d2, d3 Debug 19> d1 := "d2"; d2 := "d3"; d3 := "hello" Debug 20> ?d1 d1 => "d2" Debug 21> ? $d1 -- $d1 => d2 = "d3" d2 => "d3" Debug22> ? $$d1 -- $$d2 => d3 = "hello" d3 => "hello"
When a delayed substitution debugger variable is executed, the quotation marks are stripped off. Thus the value of d1 is the string "d2", but the delayed substitution value of $d1 is the variable d2, which has its own string value. An error occurs if you attempt to evaluate a variable that contains only a string or a literal value as a delayed substitution variable. For example:
Debug 23> ? $d3 hello ^ Undeclared identifier <8.3>
A final example of manipulating variables is:
now := time -- "now" is a program variable, -- declared STRING(1..8) history_reference := variable_reference prompt := "What can I do for you? "
Predefined Debugger Variables
The debugger defines and keeps track of the value of a number of special debugger variables, which are listed in the following table. Some variables cannot be changed, and these are indicated as read-only in the table. To change the value of debugger variables, use the := command and put quotation marks around the values. Since the debugger depends on the existence of the predefined variables, you may not delete any of them with the UNDECLARE command. Unlike a debugger command, a debugger variable must be used in its full form when referenced, since an abbreviation is not expanded.
|Variable Name||Read Only||Variable Content||Default|
|command_count||Yes||The sequential number of the next command to be executed.||N/A|
|continuation_prompt||The prompt used for the second and subsequent lines of debugger command input.||>|
|current_location||Yes||The location at which the target program is stopped. The value is the same as that displayed for the WHERE command.||N/A|
|default_unit||Yes||Default compilation unit.||Main program body|
|delayed_substitution||A debugger variable or history entry at command execution time.||$|
|editor||The command line to use for running an editor.||vi +%n %f|
|execution_count||Yes||The number of times some debugger command has caused the target program to execute one or more instructions.||N/A|
|immediate_substitution||The symbol used to refer to a debugger variable or history entry at command entry time.||!|
|line_continuation||The symbol that may be used at the end of a command line to indicate that the logical command is not complete.||\|
|main_program||Yes||The name of main procedure of the program being debugged.||Main program body|
|pager||When set to "off", the debugger will not pause and prompt for input after each screen of output.||On|
|prompt||The symbol used to prompt for command input.||"Debug $command_count>"|
|run_parameters||Yes||The list of parameters provided to the most recent LOAD command.||N/A|
|source_path||The symbol is a list of path names separated by colons, used to search for source that the debugger displays.||Null string|
|view_location||Yes||Position of current debugger view||N/A|
|view_task||Yes||Task that contains the current debugger view||N/A|
If the variable PROMPT contains variable references, the debugger substitutes the values of these variables before displaying the prompt. This allows you to include the time, the command count, and so on, as part of your command prompt. For example, you can change the prompt to include the time as well as the command count, as follows:
Debug 65> ? prompt prompt => "Debug $command_count> " Debug 66> prompt := "Debug $time $command_count> " Debug 15:40:27 67>
The COMMAND_COUNT variable is defined as an integer while the other predefined debugger variables are defined as strings.
Debugger variables can be concatenated to form new strings following the Ada string concatenation conventions. For example, it might be useful to declare a variable that contains information about a debugging session:
Debug 1> declare session Debug 2> session := main_program & date & time Debug 3> ? session session => "sorttest1989-Mar-0815:42:27"
The SHOW DEBUGGER command shows the values of all debugger variables in alphabetical order, listing the predefined variables and the user-defined variables together.
By default, SOURCE_PATH is a null string, which means the debugger will search in the current directory for C files, and in the original source file location for Ada files. If you set this variable to a non-null value, then the paths in this variable are searched for a source file if it cannot be found in the default location. This variable is analogous to the shell PATH variable.