HP OpenVMS Systems Documentation

HP OpenVMS Debugger Manual

To set a breakpoint or a tracepoint on a particular program location,
specify an address expression with the SET BREAK or SET TRACE command.

Fundamentally, an address expression specifies a memory address or a
register. Because the debugger understands the symbols associated with
your program, the address expressions you typically use with the SET
BREAK or SET TRACE command are routine names, labels, or source line
numbers rather than memory addresses---the debugger converts these
symbols to addresses.

In some cases, when using the SET BREAK or SET TRACE command with a
symbolic address expression, you might need to set a module or specify
a scope or a path name. Those concepts are described in detail in
Chapter 5. The examples in this section assume that all modules are
set and that all symbols referenced are uniquely defined, unless
otherwise indicated.

The following examples show how to set a breakpoint on a routine (SWAP)
and a tracepoint on a label (LOOP1):

DBG> SET BREAK SWAP
DBG> SET TRACE LOOP1

The next command sets a breakpoint on the return instruction of routine
SWAP. Breaking on the return instruction of a routine lets you inspect
the local environment (for example, to obtain the values of local
variables) while the routine is still active.

DBG> SET BREAK/RETURN SWAP

Some languages, for example Fortran, use numeric labels. To set a
breakpoint or a tracepoint on a numeric label, you must precede the
number with the built-in symbol %LABEL. Otherwise, the debugger
interprets the number as a memory address. For example, the following
command sets a tracepoint on label 20:

DBG> SET TRACE %LABEL 20

You can set a breakpoint or a tracepoint on a line of source code by
specifying the line number preceded by the built-in symbol %LINE. The
following command sets a breakpoint on line 14:

DBG> SET BREAK %LINE 14

The previous breakpoint causes execution to pause on the first
instruction of line 14. You can set a breakpoint or a tracepoint only
on lines for which the compiler generated instructions (lines that
resulted in executable code). If you specify a line number that is not
associated with an instruction, such as a comment line or a statement
that declares but does not initialize a variable, the debugger issues a
diagnostic message. For example:

DBG> SET BREAK %LINE 6
%DEBUG-I-LINEINFO, no line 6, previous line is 5, next line is 8
%DEBUG-E-NOSYMBOL, symbol '%LINE 6' is not in the symbol table
DBG>

The previous messages indicate that the compiler did not generate
instructions for lines 6 or 7 in this case.

Some languages allow more than one statement on a line. In such cases,
you can use statement numbers to differentiate among statements on the
same line. A statement number consists of a line number, followed by a
period (.), and a number indicating the statement. The syntax is as
follows:

%LINE line-number.statement-number

For example, the following command sets a tracepoint on the second
statement of line 38:

DBG> SET TRACE %LINE 38.2

When searching for symbols that you reference in commands, the debugger
uses the conventions described in Section 5.3.1. That is, it first
looks within the module where execution is currently paused, then in
other scopes associated with routines on the call stack, and so on.
Therefore, to specify a symbol that is defined in more than one module,
such as a line number, you might need to use a path name. For example,
the following command sets a tracepoint on line 27 of module MOD4:

DBG> SET TRACE MOD4\%LINE 27

Remember the symbol lookup conventions when specifying a line number in
debugger commands. If that line number is not defined in the module
where execution is paused (because it is not associated with an
instruction), the debugger uses the symbol lookup conventions to locate
another module where the line number is defined.

When specifying address expressions, you can combine symbolic addresses
with byte offsets. Thus, you can set a breakpoint or a tracepoint on a
particular instruction by specifying its line number and the byte
offset from the beginning of that line to the first byte of the
instruction. For example, the next command sets a breakpoint on the
address that is five bytes beyond the beginning of line 23:

To set a breakpoint or a tracepoint on a location in memory, specify
its numerical address in the currently set radix. The default radix for
both data entry and display is decimal for most languages.

On VAX processors, the exceptions are BLISS and MACRO--32, which have a
default radix of hexadecimal.

On Alpha processors, the exceptions are BLISS, MACRO--32, and MACRO--64,
which have a default radix of hexadecimal.

On I64, the exceptions are BLISS, MACRO--32, and Intel Assembler.

For example, the following command sets a breakpoint at address 2753,
decimal, or at address 2753, hexadecimal:

DBG> SET BREAK 2753

You can specify a radix when you enter an individual integer literal
(such as 2753) by using one of the built-in symbols %BIN, %OCT, %DEC,
or %HEX. For example, in the following command line the symbol %HEX
specifies that 2753 should be treated as a hexadecimal integer:

DBG> SET BREAK %HEX 2753

Note that when specifying a hexadecimal number that starts with a
letter rather than a number, you must add a leading 0. Otherwise, the
debugger tries to interpret the entity specified as a symbol declared
in your program.

For additional information about specifying radixes and about the
built-in symbols %BIN, %DEC, %HEX, and %OCT, see Section 4.1.10 and
Appendix B.

If a breakpoint or a tracepoint was set on a numerical address that
corresponds to a symbol in your program, the SHOW BREAK or SHOW TRACE
command identifies the breakpoint symbolically.

The address is displayed in the current radix. You can specify a radix
qualifier to display the address in another radix. For example:

DBG> EVALUATE/ADDRESS/HEX %LINE 26
0000065D
DBG>

The SYMBOLIZE command does the reverse of EVALUATE/ADDRESS. It converts
a memory address into its symbolic representation (including its path
name) if such a representation is possible. Chapter 5 explains how
to control symbolization. See Section 4.1.11 for more information about
obtaining and symbolizing addresses.

For example, the following command causes the debugger to break on the
beginning of every source line encountered during execution:

DBG> SET BREAK/LINE

The instruction-related qualifiers are especially useful for opcode
tracing, which is the tracing of all instructions or the tracing of a
class of instructions. The next command causes the debugger to trace
every branch instruction encountered (for example BEQL, BGTR, and so
on):

DBG> SET TRACE/BRANCH

Note that opcode tracing slows program execution.

By default, when you use the qualifiers discussed in this section, the
debugger breaks or traces within all called routines as well as within
the currently executing routine (this is equivalent to specifying SET
BREAK/INTO or SET TRACE/INTO). By specifying SET BREAK/OVER or SET
TRACE/OVER, you can suppress break or trace action within all called
routines. Or, you can use the /[NO]JSB, /[NO]SHARE, or /[NO]SYSTEM
qualifiers to specify the kinds of called routines where break or trace
action is to be suppressed. For example, the next command causes the
debugger to break on every line except within called routines that are
in shareable images or system space:

On Alpha systems, to cause the debugger to suspend program execution
when an instruction is emulated, use the command SET BREAK/SYSEMULATE.
The syntax of the SET BREAK command when using the /SYSEMULATE
qualifier is:

SET BREAK/SYSEMULATE[=mask]

The optional argument mask is a quadword with bits set
to specify which instruction groups shall trigger breakpoints. The only
emulated instruction group currently defined consists of the BYTE and
WORD instructions. Specify this instruction group by setting bit 0 of
mask to 1.

If you do not specify mask, or if
mask = FFFFFFFFFFFFFFFF, the debugger stops program
execution whenever the operating system emulates any instruction.

The SET BREAK and SET TRACE commands provide several options for
controlling the behavior of the debugger at breakpoints and
tracepoints---the /AFTER, /[NO]SILENT, /[NO]SOURCE, and /TEMPORARY
command qualifiers, and the optional WHEN and DO clauses. The following
examples show several of these options.

The following command sets a breakpoint on line 14 and specifies that
the breakpoint take effect after the fifth time that line 14 is
executed:

DBG> SET BREAK/AFTER:5 %LINE 14

The following command sets a tracepoint that is triggered at every line
of execution. The DO clause obtains the value of the variable X when
each line is executed:

DBG> SET TRACE/LINE DO (EXAMINE X)

The following example shows how you capture the WHEN and DO clauses
together. The command sets a breakpoint at line 27. The breakpoint is
triggered (execution is paused) only when the value of SUM is greater
than 100 (not each time line 27 is executed). The DO clause causes the
value of TEST_RESULT to be examined whenever the breakpoint is
triggered---that is, whenever the value of SUM is greater than 100. If
the value of SUM is not greater than 100 when execution reaches line
27, the breakpoint is not triggered and the DO clause is not executed.

The /SILENT qualifier suppresses the break or trace message and source
code display. This is useful when, for example, you want to use the SET
TRACE command only to execute a debugger command at the tracepoint. In
the following example, the SET TRACE command is used to examine the
value of the Boolean variable STATUS at the tracepoint:

In the next example, the SET TRACE command is used to count the number
of times line 12 is executed. The first DEFINE/VALUE command defines a
symbol COUNT and initializes its value to 0. The DO clause of the SET
TRACE command causes the value of COUNT to be incremented and evaluated
whenever the tracepoint is triggered (whenever execution reaches line
12).

Source lines are displayed by default at breakpoints, tracepoints, and
watchpoints if they are available for the module being debugged. You
can also control their display with the SET STEP [NO]SOURCE command and
the /[NO]SOURCE qualifier of the SET BREAK, SET TRACE, and SET WATCH
commands. See Chapter 6 for information about how to control the
display of source code in general and in particular at breakpoints,
tracepoints, and watchpoints.

The SET BREAK/EXCEPTION and SET TRACE/EXCEPTION commands direct the
debugger to treat any exception generated by your program as a
breakpoint or tracepoint, respectively. The breakpoint or tracepoint
occurs before any application-declared exception handler is invoked.
See Section 14.5 for debugging techniques associated with exceptions
and condition handlers.

The SET BREAK and SET TRACE commands each have an
/EVENT=event-name qualifier. You can use this qualifier to set
breakpoints or tracepoints that are triggered by various events
(denoted by event-name keywords). Events and their keywords are
currently defined for the following event facilities:

The appropriate facility and event-name keywords are defined when the
program is brought under debugger control. Use the SHOW EVENT_FACILITY
command to identify the current event facility and the associated
event-name keywords. The SET EVENT_FACILITY command enables you to
change the event facility and change your debugging context. This is
useful if you have a multilanguage program and want to debug a routine
that is associated with an event facility but that facility is not
currently set.

The following example shows how to set a SCAN event breakpoint. It
causes the debugger to break whenever a SCAN token is built, for any
value:

DBG> SET BREAK/EVENT=TOKEN

When a breakpoint or tracepoint is triggered, the debugger identifies
the event that caused it to be triggered and gives additional
information.

After a breakpoint or tracepoint is set, you can deactivate it,
activate it, or cancel it.

To deactivate a breakpoint or tracepoint, enter the DEACTIVATE BREAK or
DEACTIVATE TRACE command. This causes the debugger to ignore the
breakpoint or tracepoint during program execution. However, you can
activate it at a later time, for example, when you rerun the program
(see Section 1.3.3). A deactivated breakpoint or tracepoint is listed
as such in a SHOW BREAK display.

To activate a breakpoint or tracepoint, use the ACTIVATE BREAK or
ACTIVATE TRACE command. Activating a breakpoint or tracepoint causes it
to take effect during program execution.

The commands DEACTIVATE BREAK/ALL and ACTIVATE BREAK/ALL (or DEACTIVATE
TRACE/ALL and ACTIVATE TRACE/ALL) operate on all breakpoints or
tracepoints and are particularly useful when rerunning a program with
the RERUN command.

To cancel a breakpoint or tracepoint, use the CANCEL BREAK or CANCEL
TRACE command. A canceled breakpoint or tracepoint is no longer listed
in a SHOW BREAK or SHOW TRACE display.

When using any of these commands, specify the address expression and
qualifiers (if any) exactly as you did when setting the breakpoint or
tracepoint. For example:

The SET WATCH command enables you to specify program variables (or
arbitrary memory locations) that the debugger monitors as your program
executes. This process is called setting watchpoints. If, during
execution, the program modifies the value of a watched variable (or
memory location), the watchpoint is triggered. The debugger then
suspends execution, displays information, and prompts for more
commands. The debugger monitors watchpoints continuously during program
execution.

This section describes the general use of the SET WATCH command.
Section 3.4.3 gives additional information about setting watchpoints on
nonstatic variables---variables that are allocated on the call stack or
in registers.

Note

In some cases, when using the SET WATCH command with a variable name
(or any other symbolic address expression), you might need to set a
module or specify a scope or a path name. Those concepts are described
in Chapter 5. The examples in this section assume that all modules
are set and that all variable names are uniquely defined.

If your program was optimized during compilation, certain variables in
the program might be removed by the compiler. If you then try to set a
watchpoint on such a variable, the debugger issues a warning (see
Section 1.2 and Section 14.1).

You can specify any valid address expression, but usually you specify
the name of a variable. The following example shows a typical use of
the SET WATCH command and shows the general default behavior of the
debugger at a watchpoint:

In this example, the SET WATCH command sets a watchpoint on the
variable COUNT, and the GO command starts execution. When the program
changes the value of COUNT, execution is paused. The debugger then does
the following:

Announces the event ("watch of MOD2\COUNT..."),
identifying the location of the instruction that changed the value of
the watched variable ("...at MOD2\%LINE 24")

Displays the associated source line (24)

Displays the old and new values of the variable (27 and 28)

Announces that execution is paused at the beginning of the next
line ("break at MOD2\%LINE 25") and displays that source line

Prompts for another command

When the address of the instruction that modified a watched variable is
not at the beginning of a source line, the debugger denotes the
instruction's location by displaying the line number plus the byte
offset from the beginning of the line. For example:

In this example, the address of the instruction that modified variable
K is 5 bytes beyond the beginning of line 19. The breakpoint is on the
instruction that follows the instruction that modified the variable
(not on the beginning of the next source line as in the preceding
example).

You can set watchpoints on aggregates (that is, entire arrays or
records). A watchpoint set on an array or record triggers if any
element of the array or record changes. Thus, you do not need to set
watchpoints on individual array elements or record components. However,
you cannot set an aggregate watchpoint on a variant record. In the
following example, the watchpoint is triggered because element 3 of
array ARR was modified:

You can also set a watchpoint on a record component, on an individual
array element, or on an array slice (a range of array elements). A
watchpoint set on an array slice triggers if any element within that
slice changes. When setting the watchpoint, use the syntax of the
current language. For example, the following command sets a watchpoint
on element 7 of array CHECK using Pascal syntax:

DBG> SET WATCH CHECK[7]

To identify all of the watchpoints that are currently set, use the SHOW
WATCH command.