HP OpenVMS Systems Documentation
OpenVMS Debugger Manual
13.4 Defining Symbols for Commands, Address Expressions, and Values
You specify the kind of symbol you want to define by the command qualifier you use with the DEFINE command (/COMMAND, /ADDRESS, or /VALUE). The default qualifier is /ADDRESS. If you plan to enter several DEFINE commands with the same qualifier, you can first use the SET DEFINE command to establish a new default qualifier (for example, SET DEFINE COMMAND makes the DEFINE command behave like DEFINE/COMMAND). The SHOW DEFINE command identifies the default qualifier currently in effect.
Use the SHOW SYMBOL/DEFINED command to identify symbols you have defined with the DEFINE command. Note that the SHOW SYMBOL command without the /DEFINED qualifier identifies only the symbols that are defined in your program, such as the names of routines and variables.
When defining a symbol within a command procedure, use the /LOCAL
qualifier to confine the symbol definition to that command procedure.
Use the DEFINE/COMMAND command to equate one or more command strings to a shorter symbol. The basic syntax is shown in the following example:
In the example, the DEFINE/COMMAND command equates the symbol SB to the string SET BREAK (note the use of the quotation marks to delimit the command string). When the command line SB PARSER is executed, the debugger substitutes the string SET BREAK for the symbol SB and then executes the SET BREAK command.
In the following example, the DEFINE/COMMAND command equates the symbol BT to the string consisting of the SHOW BREAK command followed by the SHOW TRACE command (use semicolons to separate multiple command strings):
The SHOW SYMBOL/DEFINED command identifies the symbol BT as follows:
To define complex commands, you might need to use command procedures with parameters (see Section 13.1.2 for information about passing parameters to command procedures). For example:
13.4.2 Defining Symbols for Address Expressions
Use the DEFINE/ADDRESS command to equate an address expression to a symbol. /ADDRESS is the default qualifier for the DEFINE command, but it is used in the following examples for emphasis.
In the following example, the symbol B1 is equated to the address of line 378; the SET BREAK B1 command then sets a breakpoint on line 378:
The DEFINE/ADDRESS command is useful when you need to specify a long path name repeatedly to reference the name of a variable or routine that is defined multiple times. In the next example, the symbol UX is equated to the path name SCREEN_IO\UPDATE\X; the abbreviated command line EXAMINE UX can then be used to obtain the value of X in routine UPDATE of module SCREEN_IO:
13.4.3 Defining Symbols for Values
Use the DEFINE/VALUE command to equate the current value of a language
expression to a symbol (the current value is the value at the time the
The following example shows how you can use the DEFINE/VALUE command to count the number of calls to a routine:
In the example, the first DEFINE/VALUE command initializes the value of
the symbol COUNT to 0. The SET TRACE command sets a silent tracepoint
on routine ROUT and (through the DO clause) increments the value of
COUNT by 1 every time ROUT is called. After execution is resumed and
eventually suspended, the EVALUATE command obtains the current value of
COUNT (the number of times that ROUT was called).
To facilitate entering commonly used commands, the function keys on the keypad have predefined debugger functions that are established when you start the debugger. These predefined functions are identified in Appendix A and the debugger's online help (type HELP Keypad). You can modify the functions of the keypad keys to suit your individual needs. If you have a VT200- or VT300-series terminal or a workstation, you can also bind commands to the additional function keys on the LK201 keyboard.
The debugger commands DEFINE/KEY, SHOW KEY, and DELETE/KEY enable you to assign, identify, and delete key definitions, respectively. Before you can use this feature, keypad mode must be enabled with the SET MODE KEYPAD command (keypad mode is enabled by default). Keypad mode also enables you to use the predefined functions of the keypad keys.
To use the keypad keys to enter numbers rather than debugger commands,
enter the SET MODE NOKEYPAD command.
The debugger DEFINE/KEY command, which is similar to the DCL command DEFINE/KEY, enables you to assign a string to a function key. In the following example, the DEFINE/KEY command defines KP7 (keypad key 7) to enter and execute the SHOW MODULE * command:
You must use a valid key name (such as KP7) with the commands DEFINE/KEY, SHOW KEY, and DELETE/KEY. See the DEFINE/KEY command for the valid key names that you can use with these commands for VT52 and VT100-series terminals and for LK201 keyboards.
You can assign any number of definitions to the same function key as long as each definition is associated with a different state. The predefined states (DEFAULT, GOLD, BLUE, and so on) are identified in Appendix A and the debugger's online help (type HELP Keypad). In the preceding example, the informational message indicates that KP7 has been defined for the DEFAULT state (which is the default key state).
You can enter key definitions in a debugger initialization file (see Section 13.2) so that these definitions are available whenever you start the debugger.
To display a key definition in a state other than the current state, specify that state with the /STATE qualifier when entering the SHOW KEY command. To see all key definitions in the current state, enter the SHOW KEY/ALL command.
13.5.2 Advanced Techniques
This section shows more advanced techniques for defining keys, particularly techniques related to the use of state keys.
The following command line assigns the unterminated command string "SET BREAK %LINE" to KP9, for the BLUE state:
The predefined DEFAULT key state is established by default. The predefined BLUE key state is established by pressing the PF4 key. Enter the command line assigned in the preceding example (SET BREAK %LINE ...) by pressing PF4, pressing KP9, entering a line number, and then pressing the Return key to terminate and process the command line.
The SET KEY command enables you to change the default state for key definitions. For example, after entering the SET KEY/STATE=BLUE command, you do not need to press PF4 to enter the command line in the previous example. Also, the SHOW KEY command will show key definitions in the BLUE state, by default, and the DELETE/KEY command will delete key definitions in the BLUE state by default.
You can create additional key states. For example:
In this example, the SET KEY command establishes DEFAULT as the current
state. The DEFINE/KEY command makes F12 (LK201 keyboard) a state key.
As a result, pressing F12 while in the DEFAULT state causes the current
state to become RED. The key definition is not terminated and has no
other effect (a null string is assigned to F12). After pressing F12,
you can enter RED commands by pressing keys that have definitions
associated with the RED state.
The FOR, IF, REPEAT, and WHILE commands enable you to create looping and conditional constructs for entering debugger commands. The associated command EXITLOOP is used to exit a FOR, REPEAT, or WHILE loop. The following sections describe these commands.
The FOR command executes a sequence of commands while incrementing a variable a specified number of times. It has the following syntax:
For example, the following command line sets up a loop that initializes the first 10 elements of an array to 0:
13.6.2 IF Command
The IF command executes a sequence of commands if a language expression (Boolean expression) is evaluated as true. It has the following syntax:
The following Fortran example sets up a condition that issues the command EXAMINE X2 if X1 is not equal to - 9.9, and issues the command EXAMINE Y1 otherwise:
The following Pascal example combines a FOR loop and a condition test. The STEP command is issued if X1 is not equal to - 9.9. The test is made four times:
13.6.3 REPEAT Command
The REPEAT command executes a sequence of commands a specified number of times. It has the following syntax:
For example, the following command line sets up a loop that issues a sequence of two commands (EXAMINE Y then STEP) 10 times:
13.6.4 WHILE Command
The WHILE command executes a sequence of commands while the language expression (Boolean expression) you have specified evaluates as true. It has the following syntax:
The following Pascal example sets up a loop that repetitively tests X1 and X2 and issues the two commands EXAMINE X2 and STEP if X2 is less than X1:
13.6.5 EXITLOOP Command
The EXITLOOP command exits one or more enclosing FOR, REPEAT, or WHILE loops. It has the following syntax:
The integer n specifies the number of nested loops to exit from.
The following Pascal example sets up an endless loop that issues a STEP command with each iteration. After each step, the value of X is tested. If X is greater than 3, the EXITLOOP command terminates the loop.
13.7 Calling Routines Independently of Program Execution
The CALL command enables you to execute a routine independently of the normal execution of your program. It is one of the four debugger commands that you can use to execute your program (the others are GO, STEP, and EXIT).
The CALL command executes a routine whether or not your program actually includes a call to that routine, as long as the routine was linked with your program. Thus, you can use the CALL command to execute routines for any purpose (for example, to debug a routine out of the context of program execution, call a run-time library procedure, call a routine that dumps debugging information, and so on).
You can debug unrelated routines by linking them with a dummy main program that has a transfer address, and then using the CALL command to execute them.
The following example shows how you can use the CALL command to display some process statistics without having to include the necessary code in your program. The example consists of calls to run-time library routines that initialize a timer (LIB$INIT_TIMER) and display the elapsed time and various statistics (LIB$SHOW_TIMER). (Note that the presence of the debugger affects the timings and counts.)
The comments that follow refer to the callouts in the previous example:
The following example shows how to call LIB$SHOW_VM (also in LIBRTL) to display memory statistics. Again, note that the presence of the debugger affects the counts.