|
HP OpenVMS systems documentation |
Previous | Contents | Index |
Symbol ambiguities can occur when a symbol (for example, a variable name X) is defined in more than one routine or other program unit.
In most cases, the debugger resolves symbol ambiguities automatically. First, it uses the scope and visibility rules of the currently set language. In addition, because the debugger permits you to specify symbols in arbitrary modules (to set breakpoints and so on), the debugger uses the ordering of routine calls on the call stack to resolve symbol ambiguities.
If the debugger cannot resolve a symbol ambiguity, it issues a message. For example:
DBG> EXAMINE Y %DEBUG-W-NOUNIQUE, symbol 'Y' is not unique DBG> |
You can then use a path-name prefix to uniquely specify a declaration of the given symbol. First, use the SHOW SYMBOL command to identify all path names associated with the given symbol (corresponding to all declarations of that symbol) that are currently loaded in the RST. Then use the desired path-name prefix when referencing the symbol. For example:
DBG> SHOW SYMBOL Y data MOD7\ROUT3\BLOCK1\Y data MOD4\ROUT2\Y DBG> EXAMINE MOD4\ROUT2\Y MOD4\ROUT2\Y: 12 DBG> |
If you need to refer to a particular declaration of Y repeatedly, use the SET SCOPE command to establish a new default scope for symbol lookup. Then, references to Y without a path-name prefix specify the declaration of Y that is visible in the new scope. For example:
DBG> SET SCOPE MOD4\ROUT2 DBG> EXAMINE Y MOD4\ROUT2\Y: 12 DBG> |
To display the current scope for symbol lookup, use the SHOW SCOPE
command. To restore the default scope, use the CANCEL SCOPE command.
2.6 Sample Debugging Session
This section walks you through a debugging session with a simple Fortran program that contains a logic error (see Example 2-1). Compiler-assigned line numbers have been added in the example so that you can identify the source lines referenced in the discussion.
The program, called SQUARES, performs the following functions:
Example 2-1 Sample Program SQUARES |
---|
1: INTEGER INARR(20), OUTARR(20) 2: C 3: C ---Read the input array from the data file. 4: OPEN(UNIT=8, FILE='DATAFILE.DAT', STATUS='OLD') 5: READ(8,*) N, (INARR(I), I=1,N) 6: C 7: C ---Square all nonzero elements and store in OUTARR. 8: K = 0 9: DO 10 I = 1, N 10: IF(INARR(I) .NE. 0) THEN 11: OUTARR(K) = INARR(I)**2 12: ENDIF 13: 10 CONTINUE 14: C 15: C ---Print the squared output values. Then stop. 16: PRINT 20, K 17: 20 FORMAT(' Number of nonzero elements is',I4) 18: DO 40 I = 1, K 19: PRINT 30, I, OUTARR(I) 20: 30 FORMAT(' Element',I4,' has value',I6) 21: 40 CONTINUE 22: END |
When you run SQUARES, it produces the following output, regardless of the number of nonzero elements in the data file:
$ RUN SQUARES Number of nonzero elements is 0 |
The error in the program is that variable K, which keeps track of the current index into OUTARR, is not incremented in the loop on lines 9 through 13. The statement K = K + 1 should be inserted just before line 11.
Example 2-2 shows how to start the debugging session and then how to use the debugger to find the error. Comments, keyed to the callouts, follow the example.
Example 2-2 Sample Debugging Session Using Program SQUARES |
---|
$ FORTRAN/DEBUG/NOOPTIMIZE SQUARES (1) $ LINK/DEBUG SQUARES (2) $ DEBUG/KEEP (3) Debugger Banner and Version Number DBG> RUN SQUARES (4) Language: FORTRAN, Module: SQUARES$MAIN DBG> STEP 4 (5) stepped to SQUARES$MAIN\%LINE 9 9: DO 10 I = 1, N DBG> EXAMINE N,K (6) SQUARES$MAIN\N: 9 SQUARES$MAIN\K: 0 DBG> STEP 2 (7) stepped to SQUARES$MAIN\%LINE 11 11: OUTARR(K) = INARR(I)**2 DBG> EXAMINE I,K (8) SQUARES$MAIN\I: 1 SQUARES$MAIN\K: 0 DBG> DEPOSIT K = 1 (9) DBG> SET TRACE/SILENT %LINE 11 DO (DEPOSIT K = K + 1) (10) DBG> GO (11) Number of nonzero elements is 4 Element 1 has value 16 Element 2 has value 36 Element 3 has value 9 Element 4 has value 49 'Normal successful completion' DBG> SPAWN (12) $ EDIT SQUARES.FOR (13) . . . 10: IF(INARR(I) .NE. 0) THEN 11: K = K + 1 12: OUTARR(K) = INARR(I)**2 13: ENDIF . . . $ FORTRAN/DEBUG/NOOPTIMIZE SQUARES (14) $ LINK/DEBUG SQUARES $ LOGOUT (15) DBG> RUN SQUARES (16) Language: FORTRAN, Module: SQUARES$MAIN DBG> SET BREAK %LINE 12 DO (EXAMINE I,K) (17) DBG> GO (18) SQUARES$MAIN\I: 1 SQUARES$MAIN\K: 1 DBG> GO SQUARES$MAIN\I: 2 SQUARES$MAIN\K: 2 DBG> GO SQUARES$MAIN\I: 4 SQUARES$MAIN\K: 3 DBG> EXIT (19) $ |
The following comments apply to the callouts in Example 2-2. Example 2-1 shows the program that is being debugged.
This chapter describes how to control and monitor program execution while debugging by using the following techniques:
The following related functions are discussed in Chapter 2:
This chapter includes information that is common to all programs. For more information:
For information about rerunning your program or running another program
from the current debugging session, see Section 1.3.3 and Section 1.3.4.
3.1 Commands Used to Execute the Program
Only four debugger commands are directly associated with program execution:
GO
STEP
CALL
EXIT (if your program has exit handlers)
As explained in Section 2.3.1 and Section 2.3.2, GO and STEP are the basic commands for starting and resuming program execution. The STEP command is discussed further in Section 3.2.
During a debugging session, routines are executed as they are called during the execution of a program. The CALL command enables you to arbitrarily call and execute a routine that was linked with your program. This command is discussed in Section 13.7.
The EXIT command was discussed in Section 1.8, in conjunction with ending a debugging session. Because it executes any exit handlers in your program, it is also useful for debugging exit handlers (see Section 14.6).
When using any of these four commands, note that program execution can be interrupted or stopped by any of the following events:
The STEP command (probably the most frequently used debugger command) enables you to execute your program in small increments called step units.
By default, a step unit is an executable 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 next line to be executed:
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 of module TEST. Line 27 is in COUNT, a routine within module TEST.
The STEP command can also execute several source lines at a time. If you specify a positive integer as a parameter, the STEP command executes that number of lines. In the following example, the STEP command executes the next three lines:
DBG> STEP 3 stepped to TEST\COUNT\%LINE 34 34: SWAP(X,Y); DBG> |
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. Also, if a line has more than one statement on it, the debugger executes all the statements on that line as part of the single step.
Source lines are displayed by default after stepping if they are
available for the module being debugged. Source lines are not available
if you are stepping in code that has not been compiled or linked with
the /DEBUG qualifier (for example, a shareable image routine). If
source lines are available, you can control their display with the SET
STEP [NO]SOURCE command and the /[NO]SOURCE qualifier of the STEP
command. For information about how to control the display of source
code in general and in particular after stepping, see Chapter 6.
3.2.1 Changing the STEP Command Behavior
You can change the default behavior of the STEP command in two ways:
In the following example, the STEP/INTO command steps into a called routine when the program counter (PC) is at a call statement. The debugger displays the source line identifying the routine PRODUCT, which is called from routine COUNT of module TEST:
DBG> STEP/INTO stepped to routine TEST\PRODUCT 6: function PRODUCT(X,Y : INTEGER) return INTEGER is DBG> |
After the STEP/INTO command executes, subsequent STEP commands revert to the default behavior.
In contrast, the SET STEP command enables you to establish new defaults for the STEP command. These defaults remain in effect until another SET STEP command is entered. For example, the SET STEP INTO command causes subsequent STEP commands to behave like STEP/INTO (SET STEP LINE causes subsequent STEP commands to behave like STEP/LINE).
There is a SET STEP command parameter for each STEP command qualifier.
You can override the current STEP command defaults for the duration of
a single STEP command by specifying other qualifiers. Use the SHOW STEP
command to identify the current STEP command defaults.
3.2.2 Stepping Into and Over Routines
By default, when the PC is at a call statement and you enter the STEP command, the debugger steps over the called routine. Although the routine is executed, execution is not paused within the routine but, rather, on the beginning of the line that follows the call statement. When stepping by instruction, execution is paused on the instruction that follows a called routine's return instruction.
To step into a called routine when the PC is at a call statement, enter the STEP/INTO command. The following example shows how to step into the routine PRODUCT, which is called from routine COUNT of module TEST:
DBG> STEP stepped to TEST\COUNT\%LINE 18 18: AREA := PRODUCT(LENGTH, WIDTH); DBG> STEP/INTO stepped to routine TEST\PRODUCT 6: function PRODUCT(X,Y : INTEGER) return INTEGER is DBG> |
To return to the calling routine from any point within the called routine, use the STEP/RETURN command. It causes the debugger to step to the return instruction of the routine being executed. A subsequent STEP command brings you back to the statement that follows the routine call. For example:
DBG> STEP/RETURN stepped on return from TEST\PRODUCT\%LINE 11 to TEST\PRODUCT\%LINE 15+4 15: end PRODUCT; DBG> STEP stepped to TEST\COUNT\%LINE 19 19: LENGTH := LENGTH + 1; DBG> |
To step into several routines, enter the SET STEP INTO command to change the default behavior of the STEP command from STEP/OVER to STEP/INTO:
DBG> SET STEP INTO |
As a result of this command, when the PC is at a call statement, a STEP command suspends execution within the called routine. If you later want to step over routine calls, enter the SET STEP OVER command.
When SET STEP INTO is in effect, you can qualify the kinds of called routines that the debugger is stepping into by specifying any of the following parameters with the SET STEP command:
These parameters make it possible to step into application-defined routines and automatically step over system routines, and so on. For example, the following command directs the debugger to step into called routines in user space only. The debugger steps over routines in system space and in shareable images.
DBG> SET STEP INTO,NOSYSTEM,NOSHARE |
This section discusses using the SET BREAK and SET TRACE commands to, respectively, suspend and trace program execution. The commands are discussed together because of their similarities.
The SET BREAK command lets you specify program locations or events at which to suspend program execution (breakpoints). After setting a breakpoint, you can start or resume program execution with the GO command, letting the program run until the specified location or condition is reached. When the breakpoint is triggered, the debugger suspends execution, identifies the breakpoint, and displays the DBG> prompt. You can then enter debugger commands---for example, to determine where you are (with the SHOW CALLS command), step into a routine, examine or modify variables, and so on.
The syntax of the SET BREAK command is as follows:
SET BREAK[/qualifier[...]] [address-expression[, ...]] [WHEN (conditional-expression)] [DO (command[; ...])] |
The following example shows a typical use of the SET BREAK command and shows the general default behavior of the debugger at a breakpoint.
In this 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) where execution is paused, and prompts for another command:
DBG> SET BREAK COUNT DBG> GO . . . break at routine PROG2\COUNT 54: procedure COUNT(X,Y:INTEGER); DBG> |
The SET TRACE command lets you select program locations or events for tracing the execution of your program without stopping its execution (tracepoints). After setting a tracepoint, you can start execution with the GO command and then monitor that location, checking for unexpected behavior. By setting a tracepoint on a routine, you can also monitor the number of times it is called.
The debugger's default behavior at a tracepoint is identical to that at a breakpoint, except that program execution continues past a tracepoint. Thus, the DBG> prompt is not displayed when a tracepoint is reached and announced by the debugger.
Except for the command name, the syntax of the SET TRACE command is identical to that of the SET BREAK command:
SET TRACE[/qualifier[...]] [address-expression[, ...]] [WHEN (conditional-expression)] [DO (command[; ...])] |
The SET TRACE and SET BREAK commands have similar syntax. When using the SET TRACE command, specify address expressions, qualifiers, and the optional WHEN and DO clauses exactly as with the SET BREAK command.
Unless you use the /TEMPORARY qualifier on the SET BREAK or SET TRACE command, breakpoints and tracepoints remain in effect until you:
To identify all of the breakpoints or tracepoints that are currently set, use the SHOW BREAK or SHOW TRACE command.
To deactivate, activate, or cancel breakpoints or tracepoints, use the following commands (see Section 3.3.7):
DEACTIVATE BREAK, DEACTIVATE TRACE
ACTIVATE BREAK, ACTIVATE TRACE
CANCEL BREAK, CANCEL TRACE
The following sections describe how to specify program locations and events with the SET BREAK and SET TRACE commands.
Previous | Next | Contents | Index |