Document revision date: 19 July 1999 | |
Previous | Contents | Index |
This section explains how to perform the following tasks:
With this information you can pick program locations where you can then
test and manipulate the contents of variables as described in
Section 2.4.
2.3.1 Starting or Resuming Program Execution
Use the GO command to start or resume program execution.
After it is started with the GO command, program execution continues until one of the following events occurs:
With most programming languages, when you bring a program under debugger control, execution is initially paused directly at the beginning of the main program. Entering a GO command at this point quickly enables you to test for an infinite loop or an exception.
If an infinite loop occurs during execution, the program does not terminate, so the debugger prompt does not reappear. To obtain the prompt, interrupt execution by pressing Ctrl/C (see Section 1.4). If you are using screen mode, the pointer in the source display indicates where execution stopped. You can also use the SHOW CALLS command to identify the currently active routine calls on the call stack (see Section 2.3.3).
If an exception that is not handled by your program is signaled, the debugger interrupts execution at that point so that you can enter commands. You can then look at the source display and a SHOW CALLS display to find where execution is paused.
The most common use of the GO command is in conjunction with
breakpoints, tracepoints, and watchpoints, as described in
Section 2.3.4, Section 2.3.5, and Section 2.3.6, respectively. If you
set a breakpoint in the path of execution and then enter the GO
command, execution is paused at that breakpoint. Similarly, if you set
a tracepoint, execution is monitored through that tracepoint. If you
set a watchpoint, execution is paused when the value of the watched
variable changes.
2.3.2 Executing the Program by Step Unit
Use the STEP command to execute the program one or more step units at a time.
By default, a step unit is one line of source code. In the following example, the STEP command executes one line, reports the action ("stepped to..."), and displays the line number (27) and source code of the line to be executed next:
DBG> STEP stepped to TEST\COUNT\%LINE 27 27: X := X + 1; DBG> |
Execution is now paused at the first machine-code instruction for line 27 within routine COUNT of module TEST.
When displaying a program symbol (for example, a line number, routine name, or variable name), the debugger always uses a path name. A path name consists of the symbol plus a prefix that identifies the symbol's location. In the previous example, the path name is TEST\COUNT\%LINE 27. The leftmost element of a path name is the module name. Moving toward the right, the path name lists any successively nested routines and blocks that enclose the symbol. A backslash character (\) is used to separate elements (except when the language is Ada, where a period is used to parallel Ada syntax).
A path name uniquely identifies a symbol of your program to the debugger. In general, you need to use path names in commands only if the debugger cannot resolve a symbol ambiguity in your program (see Section 2.5). Usually the debugger can determine the symbol you mean from its context.
When using the STEP command, note that only those source lines for which code instructions were generated by the compiler are recognized as executable lines by the debugger. The debugger skips over any other lines---for example, comment lines.
You can specify different stepping modes, such as stepping by
instruction rather than by line (SET STEP INSTRUCTION). Also, by
default, the debugger steps over called routines---execution is not
paused within a called routine, although the routine is executed. By
entering the SET STEP INTO command, you direct the debugger to suspend
execution within called routines as well as within the routine in which
execution is currently paused (SET STEP OVER is the default mode).
2.3.3 Determining Where Execution Is Paused
Use the SHOW CALLS command when you are unsure where execution is paused during a debugging session (for example, after a Ctrl/C interruption).
The command displays a traceback that lists the sequence of calls leading to the routine in which execution is paused. For each routine (beginning with the one in which execution is paused), the debugger displays the following information:
For example:
DBG> SHOW CALLS module name routine name line rel PC abs PC *TEST PRODUCT 18 00000009 0000063C *TEST COUNT 47 00000009 00000647 *MY_PROG MY_PROG 21 0000000D 00000653 DBG> |
This example indicates that execution is paused at line 18 of routine
PRODUCT (in module TEST), which was called from line 47 of routine
COUNT (in module TEST), which was called from line 21 of routine
MY_PROG (in module MY_PROG).
2.3.4 Suspending Program Execution with Breakpoints
The SET BREAK command enables you to select locations at which to suspend program execution (breakpoints). You can then enter commands to check the call stack, examine the current values of variables, and so on. You resume execution from a breakpoint with the GO or STEP commands.
The following example shows a typical use of the SET BREAK command:
DBG> SET BREAK COUNT DBG> GO . . . break at routine PROG2\COUNT 54: procedure COUNT(X,Y:INTEGER); DBG> |
In the example, the SET BREAK command sets a breakpoint on routine COUNT (at the beginning of the routine's code); the GO command starts execution; when routine COUNT is encountered, execution is paused, the debugger announces that the breakpoint at COUNT has been reached ("break at ..."), displays the source line (54) at which execution is paused, and prompts for another command. At this breakpoint, you can use the STEP command to step through routine COUNT and then use the EXAMINE command (discussed in Section 2.4.1) to check on the values of X and Y.
When using the SET BREAK command, you can specify program locations using various kinds of address expressions (for example, line numbers, routine names, memory addresses, byte offsets). With high-level languages, you typically use routine names, labels, or line numbers, possibly with path names to ensure uniqueness.
Routine names and labels should be specified as they appear in the source code. Line numbers can be derived from either a source code display or a listing file. When specifying a line number, use the prefix %LINE. Otherwise, the debugger interprets the line number as a memory location. For example, the following command sets a breakpoint at line 41 of the module in which execution is paused. The breakpoint causes the debugger to suspend execution at the beginning of line 41.
DBG> SET BREAK %LINE 41 |
Note that you can set breakpoints only on lines that resulted in machine-code instructions. The debugger warns you if you try to do otherwise (for example, on a comment line). To pick a line number in a module other than the one in which execution is paused, you must specify the module's name in a path name. For example:
DBG> SET BREAK SCREEN_IO\%LINE 58 |
You can also use the SET BREAK command with a qualifier, but no parameter, to break on every line, or on every CALL instruction, and so on. For example:
DBG> SET BREAK/LINE DBG> SET BREAK/CALL |
You can set breakpoints on events, such as exceptions, or state transitions in tasking programs.
You can conditionalize a breakpoint (with a WHEN clause) or specify that a list of commands be executed at the breakpoint (with a DO clause).
To display the current breakpoints, enter the SHOW BREAK command.
To deactivate a breakpoint, enter the DEACTIVATE BREAK command, and specify the program location exactly as you did when setting the breakpoint. This causes the debugger to ignore the breakpoint 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 is listed as such in a SHOW BREAK display.
To activate a breakpoint, use the ACTIVATE BREAK command. Activating a breakpoint causes it to take effect during program execution.
The commands DEACTIVATE BREAK/ALL and ACTIVATE BREAK/ALL operate on all breakpoints and are particularly useful when rerunning a program.
To cancel a breakpoint, use the CANCEL BREAK command. A canceled
breakpoint is no longer listed in a SHOW BREAK display.
2.3.5 Tracing Program Execution with Tracepoints
The SET TRACE command enables you to select locations for tracing the execution of your program (tracepoints), without stopping its execution. After setting a tracepoint, you can start execution with the GO command and then monitor the path of execution, checking for unexpected behavior. By setting a tracepoint on a routine, you can also monitor the number of times it is called.
As with breakpoints, every time a tracepoint is reached, the debugger issues a message and displays the source line. But the program continues executing, and the debugger prompt is not displayed. For example:
DBG> SET TRACE COUNT DBG> GO trace at routine PROG2\COUNT 54: procedure COUNT(X,Y:INTEGER); . . . |
This is the only difference between a breakpoint and a tracepoint. When
using the SET TRACE command, you specify address expressions,
qualifiers, and optional clauses exactly as with the SET BREAK command.
The commands SHOW TRACE, ACTIVATE TRACE, DEACTIVATE TRACE, and CANCEL
TRACE operate on tracepoints in a manner similar to the corresponding
commands for breakpoints (see Section 2.3.4).
2.3.6 Monitoring Changes in Variables with Watchpoints
The SET WATCH command enables you to specify program variables that the debugger monitors as your program executes. This process is called setting watchpoints. If the program modifies the value of a watched variable, the debugger suspends execution and displays information. The debugger monitors watchpoints continuously during program execution. (Note that you can also use the SET WATCH command to monitor arbitrary program locations, not just variables.)
The technique you use to set watchpoints depends on your system (VAX or Alpha) and the type of variable (static or nonstatic).
On VAX processors, you can set a watchpoint on a static variable by specifying the variable's names with the SET WATCH command. Since a static variable is associated with the same memory address throughout program execution, this variable name is always meaningful. For example, the following command sets a watchpoint on the variable TOTAL:
DBG> SET WATCH TOTAL |
Subsequently, every time the program modifies the value of TOTAL, the watchpoint is triggered.
The following example shows what happens when your program modifies the contents of this watched variable:
DBG> SET WATCH TOTAL DBG> GO . . . watch of SCREEN_IO\TOTAL at SCREEN_IO\%LINE 13 13: TOTAL = TOTAL + 1; old value: 16 new value: 17 break at SCREEN_IO\%LINE 14 14: POP(TOTAL); DBG> |
In this example, a watchpoint is set on the variable TOTAL and execution is started. When the value of TOTAL changes, execution is paused. The debugger announces the event ("watch of..."), identifying where TOTAL changed (the beginning of line 13) and the associated source line. The debugger then displays the old and new values and announces that execution has been paused at the beginning of the next line (14). Finally, the debugger prompts for another command. When a change in a variable occurs at a point other than the beginning of a source line, the debugger gives the line number plus the byte offset from the beginning of the line.
On VAX processors and Alpha processors, you can set a watchpoint on a nonstatic variable by setting a tracepoint on the defining routine and specifying a DO clause to set the watchpoint whenever execution reaches the tracepoint. Since a nonstatic variable is allocated on the stack or in a register and exists only when its defining routine is active (on the call stack), the variable name is not always meaningful in the way that a static variable name is.
In the following example, a watchpoint is set on the nonstatic variable Y in routine ROUT3. After the tracepoint is triggered, the WPTTRACE message indicates that the nonstatic watchpoint is set, and the watchpoint is triggered when the value of Y changes. For example:
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 calling routine, the nonstatic variable is no longer active, so the debugger automatically cancels the watchpoint and issues a message to that effect.
On Alpha processors, the debugger treats all watchpoints as nonstaticwatchpoints.
The commands SHOW WATCH, ACTIVATE WATCH, DEACTIVATE WATCH, and CANCEL
WATCH operate on watchpoints in a manner similar to the corresponding
commands for breakpoints (see Section 2.3.4). However, a nonstatic
watchpoint exists only as long as execution remains within the scope of
the variable being watched.
2.4 Examining and Manipulating Program Data
This section explains how to use the EXAMINE, DEPOSIT, and EVALUATE
commands to display and modify the contents of variables and evaluate
expressions. Before you can examine or deposit into a nonstatic
variable, as defined in Section 2.3.6, its defining routine must be
active.
2.4.1 Displaying the Value of a Variable
To display the current value of a variable, use the EXAMINE command. It has the following syntax:
EXAMINE address-expression |
The debugger recognizes the compiler-generated data type of the variable you specify and retrieves and formats the data accordingly. The following examples show some uses of the EXAMINE command.
Examine a string variable:
DBG> EXAMINE EMPLOYEE_NAME PAYROLL\EMPLOYEE_NAME: "Peter C. Lombardi" DBG> |
Examine three integer variables:
DBG> EXAMINE WIDTH, LENGTH, AREA SIZE\WIDTH: 4 SIZE\LENGTH: 7 SIZE\AREA: 28 DBG> |
Examine a two-dimensional array of real numbers (three per dimension):
DBG> EXAMINE REAL_ARRAY PROG2\REAL_ARRAY (1,1): 27.01000 (1,2): 31.00000 (1,3): 12.48000 (2,1): 15.08000 (2,2): 22.30000 (2,3): 18.73000 DBG> |
Examine element 4 of a one-dimensional array of characters:
DBG> EXAMINE CHAR_ARRAY(4) PROG2\CHAR_ARRAY(4): 'm' DBG> |
Examine a record variable (COBOL example):
DBG> EXAMINE PART INVENTORY\PART: ITEM: "WF-1247" PRICE: 49.95 IN_STOCK: 24 DBG> |
Examine a record component (COBOL example):
DBG> EXAMINE IN_STOCK OF PART INVENTORY\IN-STOCK of PART: IN_STOCK: 24 DBG> |
You can use the EXAMINE command with any kind of address expression
(not just a variable name) to display the contents of a program
location. The debugger associates certain default data types with
untyped locations. You can override the defaults for typed and untyped
locations if you want the data interpreted and displayed in some other
data format.
2.4.2 Assigning a Value to a Variable
To assign a new value to a variable, use the DEPOSIT command. It has the following syntax:
DEPOSIT address-expression = language-expression |
The DEPOSIT command is like an assignment statement in most programming languages.
In the following examples, the DEPOSIT command assigns new values to different variables. The debugger checks that the value assigned, which can be a language expression, is consistent with the data type and dimensional constraints of the variable.
Deposit a string value (it must be enclosed in quotation marks (") or apostrophes ('):
DBG> DEPOSIT PART_NUMBER = "WG-7619.3-84" |
Deposit an integer expression:
DBG> DEPOSIT WIDTH = CURRENT_WIDTH + 10 |
Deposit element 12 of an array of characters (you cannot deposit an entire array aggregate with a single DEPOSIT command, only an element):
DBG> DEPOSIT C_ARRAY(12) := 'K' |
Deposit a record component (you cannot deposit an entire record aggregate with a single DEPOSIT command, only a component):
DBG> DEPOSIT EMPLOYEE.ZIPCODE = 02172 |
Deposit an out-of-bounds value (X was declared as a positive integer):
DBG> DEPOSIT X = -14 %DEBUG-I-IVALOUTBNDS, value assigned is out of bounds at or near DEPOSIT |
As with the EXAMINE command, you can specify any kind of address
expression (not just a variable name) with the DEPOSIT command. You can
override the defaults for typed and untyped locations if you want the
data interpreted in some other data format.
2.4.3 Evaluating Language Expressions
To evaluate a language expression, use the EVALUATE command. It has the following syntax:
EVALUATE language-expression |
The debugger recognizes the operators and expression syntax of the currently set language. In the following example, the value 45 is assigned to the integer variable WIDTH; the EVALUATE command then obtains the sum of the current value of WIDTH and 7:
DBG> DEPOSIT WIDTH := 45 DBG> EVALUATE WIDTH + 7 52 DBG> |
In the next example, the values TRUE and FALSE are assigned to the Boolean variables WILLING and ABLE, respectively; the EVALUATE command then obtains the logical conjunction of these values:
DBG> DEPOSIT WILLING := TRUE DBG> DEPOSIT ABLE := FALSE DBG> EVALUATE WILLING AND ABLE False DBG> |
To have full access to the symbols that are associated with your program (variable names, routine names, source code, line numbers, and so on), you must compile and link the program using the /DEBUG qualifier, as explained in Section 1.2.
Under these conditions, the way in which the debugger handles these symbols is transparent to you in most cases. However, the following two areas might require action:
To facilitate symbol searches, the debugger loads symbol information from the executable image into a run-time symbol table (RST), where that information can be accessed efficiently. Unless symbol information is in the RST, the debugger does not recognize or properly interpret the associated symbols.
Because the RST takes up memory, the debugger loads it dynamically, anticipating what symbols you might want to reference in the course of program execution. The loading process is called module setting, because all symbol information for a given module is loaded into the RST at one time.
Initially, only the module containing the image transfer address is set. Subsequently, whenever execution of the program is interrupted, the debugger sets the module that contains the routine in which execution is paused. This enables you to reference the symbols that should be visible at that location.
If you try to reference a symbol in a module that has not been set, the debugger warns you that the symbol is not in the RST. For example:
DBG> EXAMINE K %DEBUG-W-NOSYMBOL, symbol 'K' is not in symbol table DBG> |
You must use the SET MODULE command to set the module containing that symbol explicitly. For example:
DBG> SET MODULE MOD3 DBG> EXAMINE K MOD3\ROUT2\K: 26 DBG> |
The SHOW MODULE command lists the modules of your program and identifies which modules are set.
Dynamic module setting can slow the debugger down as more and more modules are set. If performance becomes a problem, you can use the CANCEL MODULE command to reduce the number of set modules, or you can disable dynamic module setting by entering the SET MODE NODYNAMIC command (SET MODE DYNAMIC enables dynamic module setting).
Previous | Next | Contents | Index |
privacy and legal statement | ||
4538PRO_004.HTML |