[Digital logo]
[HR]

OpenVMS Debugger Manual


Previous | Contents

When using these qualifiers, do not specify an address expression.

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:

DBG> SET BREAK/LINE/NOSHARE/NOSYSTEM

3.3.3 Setting Breakpoints on Emulated Instructions (Alpha Only)

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.

3.3.4 Controlling Debugger Action at Breakpoints or Tracepoints

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.

DBG> SET BREAK %LINE 27 WHEN (SUM > 100) DO (EXAMINE TEST_RESULT)

See Section 4.1.6 and Section 13.3.2.2 for information about evaluating language expressions like SUM > 100.

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:

DBG> SET TRACE/SILENT %LINE 83 DO (EXAMINE STATUS)
DBG> GO
   .
   .
   .
SCREEN_IO\CLEAR\STATUS:   OFF
   .
   .
   .

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

DBG> DEFINE/VALUE COUNT=0
DBG> SET TRACE/SILENT %LINE 12 DO (DEF/VAL COUNT=COUNT+1;EVAL COUNT)

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.

3.3.5 Setting Breakpoints or Tracepoints on Exceptions

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 13.5 for debugging techniques associated with exceptions and condition handlers.

3.3.6 Setting Breakpoints or Tracepoints on Events

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.

3.3.7 Deactivating, Activating, and Canceling Breakpoints or Tracepoints

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:

DBG> DEACTIVATE TRACE/LINE
DBG> CANCEL BREAK SWAP,MOD2\LOOP4,2753

3.4 Monitoring Changes in Variables and Other Program Locations

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 13.1).


The syntax of the SET WATCH command is as follows:

SET WATCH[/qualifier[...]] address-expression[, ...] 
[WHEN (conditional-expression)] 
[DO (command[; ...])] 

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:

DBG> SET WATCH COUNT
DBG> GO
   .
   .
   .
watch of MOD2\COUNT at MOD2\%LINE 24 
     24:   COUNT := COUNT + 1; 
    old value: 27 
    new value: 28 
break at MOD2\%LINE 25 
     25:   END;
DBG>

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:

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:

DBG> SET WATCH K
DBG> GO
   .
   .
   .
watch of TEST\K at TEST\%LINE 19+5 
     19:   DO 40 K = 1, J 
    old value: 4 
    new value: 5 
break at TEST\%LINE 19+9 
     19:   DO 40 K = 1, J
DBG>

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:

DBG> SET WATCH ARR
DBG> GO
   .
   .
   .
watch of SUBR\ARR at SUBR\%LINE 12
    12:     ARR(3) := 28
   old value:
    (1):         7
    (2):         12
    (3):         3
    (4):         0
 
   new value:
    (1):         7
    (2):         12
    (3):         28
    (4):         0
 
break at SUBR\%LINE 13
DBG>

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.

3.4.1 Deactivating, Activating, and Canceling Watchpoints

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

To deactivate a watchpoint, use the DEACTIVATE WATCH command. This causes the debugger to ignore the watchpoint 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 watchpoint is listed as such in a SHOW WATCH display.

To activate a watchpoint, use the ACTIVATE WATCH command. Activating a watchpoint causes it to take effect during program execution. You can always activate a static watchpoint, but the debugger cancels a nonstatic watchpoint if execution moves out of the scope in which the variable is defined (see Section 3.4.3).

The commands DEACTIVATE WATCH/ALL and ACTIVATE WATCH/ALL operate on all watchpoints and are particularly useful when rerunning a program with the RERUN command.

To cancel a watchpoint, use the CANCEL WATCH command. A canceled watchpoint is no longer listed in a SHOW WATCH display.

3.4.2 Watchpoint Options

The SET WATCH command provides the same options for controlling the behavior of the debugger at watchpoints that the SET BREAK and SET TRACE commands provide for breakpoints and tracepoints---namely the /AFTER, /[NO]SILENT, /[NO]SOURCE, and /TEMPORARY qualifiers, and the optional WHEN and DO clauses. See Section 3.3.4 for examples.

3.4.3 Watching Nonstatic Variables


Note

The generic term nonstatic variable is used here to denote what is called an automatic variable in some languages.

Storage for a variable in your program is allocated either statically or nonstatically. A static variable is associated with the same memory address throughout execution of the program. A nonstatic variable is allocated on the call stack or in a register and has a value only when its defining routine is active on the call stack. As explained in this section, the technique for setting a watchpoint, the watchpoint's behavior, and the speed of program execution are different for the two kinds of variables.

To determine how a variable is allocated, use the EVALUATE/ADDRESS command. A static variable generally has its address in P0 space (0 to 3FFFFFFF, hexadecimal). A nonstatic variable generally has its address in P1 space (40000000 to 7FFFFFFF, hexadecimal) or is in a register. In the following Pascal code example, X is declared as a static variable, but Y is a nonstatic variable (by default). The EVALUATE/ADDRESS command, entered while debugging, shows that X is allocated at memory location 512, but Y is allocated in register R0.

   .
   .
   .
VAR 
     X: [STATIC] INTEGER; 
     Y: INTEGER; 
   .
   .
   .
DBG> EVALUATE/ADDRESS X
512
DBG> EVALUATE/ADDRESS Y
%R0
DBG>

When using the SET WATCH command, note the following distinction. You can set a watchpoint on a static variable throughout execution of your program, but you can set a watchpoint on a nonstatic variable only when execution is paused within the scope of the variable's defining routine. Otherwise, the debugger issues a warning. For example:

DBG> SET WATCH Y
%DEBUG-W-SYMNOTACT, nonstatic variable 'MOD4\ROUT3\Y' 
    is not active
DBG>

Section 3.4.3.2 describes how to set a watchpoint on a nonstatic variable.

3.4.3.1 Execution Speed

When a watchpoint is set, the speed of program execution depends on whether the variable is static or nonstatic. To watch a static variable, the debugger write-protects the page containing the variable. If your program attempts to write to that page (modify the value of that variable), an access violation occurs and the debugger handles the exception. The debugger temporarily unprotects the page to allow the instruction to complete and then determines whether the watched variable was modified. Except when writing to that page, the program executes at full speed.

Because problems arise if the call stack or registers are write-protected, the debugger must use another technique to watch a nonstatic variable. It traces every instruction in the variable's defining routine and checks the value of the variable after each instruction has been executed. Because this significantly slows down the execution of the program, the debugger issues the following message when you set a nonstatic watchpoint:

DBG> SET WATCH Y
%DEBUG-I-WPTTRACE, nonstatic watchpoint, tracing every instruction
DBG>

3.4.3.2 Setting a Watchpoint on a Nonstatic Variable

To set a watchpoint on a nonstatic variable, make sure that execution is paused within the defining routine. A convenient technique is to set a tracepoint on the routine that includes a DO clause to set the watchpoint. Thus, whenever the routine is called, the tracepoint is triggered and the watchpoint is automatically set on the local variable. In the following example, the WPTTRACE message indicates that a watchpoint has been set on Y, a nonstatic variable that is local to routine ROUT3:

DBG> SET TRACE/NOSOURCE ROUT3 DO (SET WATCH Y)
DBG> GO
   .
   .
   .
trace at routine MOD4\ROUT3
%DEBUG-I-WPTTRACE, nonstatic watchpoint, tracing every instruction
   .
   .
   .
watch of MOD4\ROUT3\Y at MOD4\ROUT3\%LINE 16
   16:     Y := 4
   old value:    3
   new value:    4
break at MOD4\ROUT3\%LINE 17
   17:     SWAP(X,Y);
DBG>

When execution returns to the caller of routine ROUT3, variable Y is no longer active. Therefore, the debugger automatically cancels the watchpoint and issues the following messages:

%DEBUG-I-WATCHVAR, watched variable MOD4\ROUT3\Y has gone out of scope
%DEBUG-I-WATCHCAN, watchpoint now canceled

3.4.3.3 Options for Watching Nonstatic Variables

The SET WATCH command qualifiers /OVER, /INTO, and /[NO]STATIC provide options for watching nonstatic variables.

When you set a watchpoint on a nonstatic variable, you can direct the debugger to do one of two things at a routine call:

Using the SET WATCH/OVER command results in better performance. However, if the called routine modifies the watched variable, the watchpoint is triggered only after execution returns from that routine. The SET WATCH/INTO command slows down program execution but enables you to monitor watchpoints more precisely within called routines.

The debugger determines whether a variable is static or nonstatic by looking at its address (P0 space, P1 space, or register). When entering a SET WATCH command, you can override this decision with the /[NO]STATIC qualifier. For example, if you have allocated nonstack storage in P1 space, use the SET WATCH/STATIC command to specify that a particular variable is static even though it is in P1 space. Conversely, if you have allocated your own call stack in P0 space, use the SET WATCH/NOSTATIC command to specify that a particular variable is nonstatic even though it is in P0 space.

3.4.3.4 Setting Watchpoints in Installed Writable Shareable Images

When setting a watchpoint in an installed writable shareable image, use the SET WATCH/NOSTATIC command (see Section 3.4.3.3).

The reason you must set a nonstatic watchpoint is as follows. Variables declared in such shareable images are typically static variables. By default, the debugger watches a static variable by write-protecting the page containing that variable. However, the debugger cannot write-protect a page in an installed writable shareable image. Therefore, the debugger must use the slower method of detecting changes, as for nonstatic variables---that is, by checking the value at the watched location after each instruction has been executed (see Section 3.4.3.1).

If any other process modifies the watched location's value, the debugger may report that your program modified the watched location.


Chapter 4
Examining and Manipulating Program Data

This chapter explains how to use the EXAMINE and DEPOSIT commands to display and modify the values of symbols declared in your program as well as the contents of arbitrary program locations. The chapter also explains how to use the EVALUATE and other commands that evaluate language expressions.

The topics covered in this chapter are organized as follows:

The examples in this chapter do not cover all language-dependent behavior. When debugging in any language, be sure also to consult the following documentation:

4.1 General Concepts

This section introduces the EXAMINE, DEPOSIT, and EVALUATE commands and discusses concepts that are common to those commands.

4.1.1 Accessing Variables While Debugging


Note

The generic term nonstatic variable is used here to denote what is called an automatic variable in some languages.

Before you try to examine or deposit into a nonstatic (stack-local or register) variable, its defining routine must be active on the call stack. That is, program execution must be paused somewhere within the defining routine. See Section 3.4.3 for more information about nonstatic variables.

You can examine a static variable at any time during program execution, and you can examine a nonstatic variable as soon as execution reaches its defining routine. However, before you examine any variable, you should execute the program beyond the point where the variable is declared and initialized. The value contained in any uninitialized variable should be considered invalid.

Many compilers optimize code to make the program run faster. If the code that you are debugging has been optimized, some program locations might not match what you would expect from looking at the source code. In particular, some optimization techniques eliminate certain variables so that you no longer have access to them while debugging.

Section 13.1 explains the effect of several optimization techniques on the executable code. When first debugging a program, it is best to disable optimization, if possible, with the /NOOPTIMIZE (or equivalent) compiler command qualifier.

In some cases, when using the EXAMINE or DEPOSIT 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 chapter assume that all modules are set and that all variable names are uniquely defined.

4.1.2 Using the EXAMINE Command

For high-level language programs, the EXAMINE command is used mostly to display the current value of variables, and it has the following syntax:

EXAMINE address-expression[,...] 

For example, the following command displays the current value of the integer variable X:

DBG> EXAMINE X
MOD3\X:   17
DBG>

When displaying the value, the debugger prefixes the variable name with its path name---in this case, the name of the module where variable X is declared (see Section 5.3.2).

The EXAMINE command usually displays the current value of the entity, denoted by an address expression, in the type associated with that location (for example, integer, real, array, record, and so on).


Previous | Next | Contents | [Home] | [Comments] | [Ordering info] | [Help]

[HR]

  4538P005.HTM
  OSSG Documentation
  22-NOV-1996 13:01:36.75

Copyright © Digital Equipment Corporation 1996. All Rights Reserved.

Legal