HP OpenVMS Systems Documentation

OpenVMS Debugger Manual

The DEFINE command enables you both to create a symbol for a lengthy or
often-repeated command sequence or address expression and to store the
value of a language expression in a symbol.

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.

Use the DELETE command to delete symbol definitions created with the
DEFINE command.

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:

DBG> DEFINE/COMMAND SB = "SET BREAK"
DBG> SB PARSER

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):

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:

DBG> DEFINE/ADDRESS B1 = %LINE 378
DBG> SET BREAK B1

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:

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.

In the previous example, the /TERMINATE qualifier indicates that
pressing KP7 executes the command. You do not have to press Return
after pressing KP7.

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 the current state, enter the SHOW KEY
command. For example:

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.

To delete a key definition, use the DELETE/KEY command. To delete a key
definition in a state other than the current state, specify that state
with the /STATE qualifier. For example:

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:

DBG> DEFINE/KEY/IF_STATE=BLUE KP9 "SET BREAK %LINE"

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.

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 EXITLOOP command exits one or more enclosing FOR, REPEAT, or WHILE
loops. It has the following syntax:

EXITLOOP [integer]

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.

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 routines LIB$INIT_TIMER and
LIB$SHOW_TIMER are in the shareable image LIBRTL. This image must be
set by setting its module, because only its universal symbols are
accessible during a debugging session (see Section 5.4.2.3).

This CALL command executes the routine
LIB$INIT_TIMER.

The value returned message indicates the
value returned in register R0 after the CALL command has been executed.
By convention, after a called routine has executed, register R0
contains the function return value (if the routine is a function) or
the procedure completion status (if the routine is a procedure that
returns a status value). If a called procedure does not return a status
value or function value, the value in R0 might be meaningless, and the
value returned message can be ignored.

This CALL command executes the routine
LIB$SHOW_TIMER.

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.