Previous | Contents | Index |
All the concepts covered in Section 5.1, Section 5.2, and Section 5.3 apply to the modules of a single image, namely the main (executable) image. This section provides additional information that is specific to debugging shareable images.
When you link shareable images for debugging as explained in Section 5.4.1, the linker builds a DST and a GST for each image. The GST for a shareable image contains only universal symbols. To conserve memory, the debugger builds an RST for an image only when that image is set, either dynamically by the debugger or when you use a SET IMAGE command.
The SHOW IMAGE command identifies all shareable images that are linked with your program, shows which images are set, and identifies the current image (see Section 5.4.2.2 for a definition of the current image). Only the main image is set initially when you bring the program under debugger control.
The following sections explain how the debugger sets images dynamically during program execution and how you can access symbols in arbitrary images independently of execution.
See Section 3.4.3.4 for information about setting watchpoints in
installed writable shareable images.
5.4.2.1 Accessing Symbols in the PC Scope (Dynamic Mode)
By default, dynamic mode is enabled. Therefore, whenever the debugger interrupts execution, the debugger sets the image and module where execution is paused, if they are not already set.
Dynamic mode gives you the following access to symbols automatically:
By setting other modules in that image with the SET MODULE command, you can reference any symbol defined in the image.
After an image is set, it remains set until you cancel it with the
CANCEL IMAGE command. If the debugger slows down as more images and
modules are set, use the CANCEL IMAGE command. You can also enter the
SET MODE NODYNAMIC command to disable dynamic mode.
5.4.2.2 Accessing Symbols in Arbitrary Images
The last image that you or the debugger sets is the current image. The current image is the debugging context for symbol lookup. Therefore, when using the following commands, you can reference only the symbols that are defined in the current image:
DEFINE/ADDRESS
DEFINE/VALUE
DEPOSIT
EVALUATE
EXAMINE
TYPE
(SET,CANCEL) BREAK
(SET,SHOW,CANCEL) MODULE
(SET,CANCEL) TRACE
(SET,CANCEL) WATCH
SHOW SYMBOL
Note that the SHOW BREAK, SHOW TRACE, and SHOW WATCH commands identify any breakpoints, tracepoints, or watchpoints that have been set in all images.
To reference a symbol in another image, use the SET IMAGE command to make the specified image the current image, then use the SET MODULE command to set the module where that symbol is defined (the SET IMAGE command does not set any modules). The following sample program shows these concepts.
The sample program consists of a main image PROG1 and a shareable image SHR1. Assume that you have just brought the program under debugger control and that execution is paused within the main program unit in image PROG1. Assume that you want to set a breakpoint on routine ROUT2, which is defined in some module in image SHR1.
If you try to set a breakpoint on ROUT2, the debugger looks for ROUT2 in the current image, PROG1:
DBG> SET BREAK ROUT2 %DEBUG-E-NOSYMBOL, symbol 'ROUT2' is not in symbol table DBG> |
The SHOW IMAGE command shows that image SHR1 needs to be set:
DBG> SHOW IMAGE image name set base address end address *PROG1 yes 00000200 000009FF SHR1 no 00001000 00001FFF total images: 2 bytes allocated: 32856 DBG> SET IMAGE SHR1 DBG> SHOW IMAGE image name set base address end address PROG1 yes 00000200 000009FF *SHR1 yes 00001000 00001FFF total images: 2 bytes allocated: 41948 DBG> |
SHR1 is now set and is the current image. However, because the SET IMAGE command does not set any modules, you must set the module where ROUT2 is defined before you can set the breakpoint:
DBG> SET BREAK ROUT2 %DEBUG-E-NOSYMBOL, symbol 'ROUT2' is not in symbol table DBG> SET MODULE/ALL DBG> SET BREAK ROUT2 DBG> GO break at routine ROUT2 10: SUBROUTINE ROUT2(A,B) DBG> |
Now that you have set image SHR1 and all its modules and have reached the breakpoint at ROUT2, you can debug using the normal method (for example, step through the routine, examine variables, and so on).
After you have set an image and set modules within that image, the
image and modules remain set even if you establish a new current image.
However, you have access to symbols only in the current image at any
one time.
5.4.2.3 Accessing Universal Symbols in Run-Time Libraries and System Images
The following paragraphs describe how to access a universal symbol (such as a routine name) in a run-time library or other shareable image for which no symbol-table information was generated. With this information you can, for example, use the CALL command to execute a run-time library or system service routine as explained in Section 13.7.
Enter the SET MODULE command with the following command syntax:
SET MODULE SHARE$image-name |
For example:
DBG> SET MODULE SHARE$LIBRTL |
The debugger creates dummy modules for each shareable image in your program. The names of these shareable image modules have the prefix SHARE$. The command SHOW MODULE/SHARE identifies these shareable image modules as well as the modules in the current image.
Once a shareable image module has been set with the SET MODULE command, you can access all of the image's universal symbols. For example, the following command lists all of the universal symbols in LIBRTL:
DBG> SHOW SYMBOL * IN SHARE$LIBRTL . . . routine SHARE$LIBRTL\STR$APPEND routine SHARE$LIBRTL\STR$DIVIDE routine SHARE$LIBRTL\STR$ROUND . . . routine SHARE$LIBRTL\LIB$WAIT routine SHARE$LIBRTL\LIB$GETDVI . . . |
You can then specify these universal symbols with, for example, the CALL or SET BREAK command.
Setting a shareable image module with the SET MODULE command loads the
universal symbols for that image into the run-time symbol table so that
you can reference these symbols from the current image. However, you
cannot reference other (local or global) symbols in that image from the
current image. That is, your debugging context remains set to the
current image.
5.4.3 Debugging Resident Images (Alpha Only)
A resident image is a shareable module that is created and installed in a particular way to enhance its efficiency. The requirements of creating such an image include linking the image without a symbol table, and running the image in system space. These requirements make such an image difficult to debug. The following procedure creates a resident image that can be more easily debugged.
$ CC/DEBUG/NOOPTIMIZE RESIDENTMODULE.C |
$ LINK/NOTRACEBACK/SHAREABLE/SECTION_BINDING/DSF RESIDENTMODULE |
$ CC/DEBUG/NOOPTIMIZE TESTPROGRAM |
$ LINK/DSF TESTPROGRAM |
$ COPY SYS$LIBRARY:RESIDENTMODULE.EXE []RESIDENTMODULE.EXE |
$ DEFINE RESIDENTMODULE []RESIDENTMODULE |
$ DEBUG/KEEP TESTPROGRAM |
You should now have access to all debugging options for the executable and resident images.
The term source code refers to statements in a programming language as they appear in a source file. Each line of source code is also called a source line.
This chapter covers the following topics:
The techniques described in this chapter apply to screen mode as well as line (noscreen) mode. Any difference in behavior between line mode and screen mode is identified in this chapter and in the descriptions of the commands discussed. (Screen mode is described in Chapter 7.)
If your program has been optimized by the compiler, the code that is
executing as you debug might not always match your source code. See
Section 14.1 for more information.
6.1 How the Debugger Obtains Source Code Information
When a compiler processes source files to generate object modules, it assigns a line number to each source line sequentially. For most languages, each compilation unit (module) starts with line 1. For other languages like Ada, each source file, which might represent several compilation units, starts with line 1.
Line numbers appear in a source listing obtained with the /LIST compile-command qualifier. They also appear whenever the debugger displays source code, either in line mode or screen mode. Moreover, you can specify line numbers with several debugger commands (for example, TYPE and SET BREAK).
The debugger displays source lines only if you have specified the
/DEBUG command with both the compile command and the LINK command.
Under these conditions, the symbol information created by the compiler
and passed to the debug symbol table (DST) includes source-line
correlation records. For a given module, source-line correlation
records contain the full file specification of each source file that
contributes to that module. In addition, they associate source records
(symbols, types, and so on) with source files and line numbers in the
module.
6.2 Specifying the Location of Source Files
The debug symbol table (DST) contains the full file specification of each source file when it was compiled. By default, the debugger expects a source file to be in the same directory it was in at compile time. If a source file is moved to a different directory after it is compiled, the debugger does not find it and issues a warning such as the following when attempting to display source code from that file:
%DEBUG-W-UNAOPNSRC, unable to open source file DISK:[JONES.WORK]PRG.FOR;2 |
In such cases, use the SET SOURCE command to direct the debugger to the new directory. The command can be applied to all source files for your program or to only the source files for specific modules.
For example, after you enter the following command line, the debugger looks for all source files in WORK$:[JONES.PROG3]:
DBG> SET SOURCE WORK$:[JONES.PROG3] |
You can specify a directory search list with the SET SOURCE command. For example, after the following command line is entered, the debugger looks for source files first in the current default directory ([]) and then in WORK$:[JONES.PROG3]:
DBG> SET SOURCE [], WORK$:[JONES.PROG3] |
If you want to apply the SET SOURCE command only to the source files for a given module, use the /MODULE=module-name qualifier and specify that module. For example, the following command line specifies that the source files for module SCREEN_IO are in the directory DISK2:[SMITH.SHARE] (the search of source files for other modules is not affected by this command):
DBG> SET SOURCE/MODULE=SCREEN_IO DISK2:[SMITH.SHARE] |
To summarize, the SET SOURCE/MODULE command specifies the location of source files for a particular module, but the SET SOURCE command specifies the location of source files for modules that were not mentioned explicitly in SET SOURCE/MODULE commands.
When you enter a SET SOURCE command, be aware that one of the two qualifiers, /LATEST or /EXACT, will always be active. The /LATEST qualifier directs the debugger to search for the latest version of your source files (the highest-numbered version in your directory). The /EXACT qualifier, the default, directs the debugger to search for the version last compiled (the version recorded in the debugger symbol table created at compile time). For example, A SET SOURCE/LATEST command might search for SORT.FOR;3 while a SET SOURCE/EXACT command might search for SORT.FOR;1.
Use the SHOW SOURCE command to display all source directory search lists currently in effect. The command displays the search lists for specific modules (as previously established by one or more SET SOURCE/MODULE commands) and the search list for all other modules (as previously established by a SET SOURCE command). For example:
DBG> SET SOURCE [PROJA],[PROJB],USER$:[PETER.PROJC] DBG> SET SOURCE/MODULE=COBOLTEST [], DISK$2:[PROJD] DBG> SHOW SOURCE source directory search list for COBOLTEST: [] DISK$2:[PROJD] source directory search list for all other modules: [PROJA] [PROJB] USER$:[PETER.PROJC] DBG> |
If no SET SOURCE or SET SOURCE/MODULE command has been entered, the SHOW SOURCE command indicates that no search list is currently in effect.
Use the CANCEL SOURCE command to cancel the effect of a previous SET SOURCE command. Use the CANCEL SOURCE/MODULE command to cancel the effect of a previous SET SOURCE/MODULE command (specifying the same module name).
When a source directory search list has been canceled, the debugger again expects the source files corresponding to the designated modules to be in the same directories they were in at compile time.
For more information about how the debugger locates source files that
have been moved to another directory after compile time, see the
SET SOURCE command.
6.3 Displaying Source Code by Specifying Line Numbers
The TYPE command enables you to display source lines by specifying compiler-assigned line numbers, where each line number designates a line of source code.
For example, the following command displays line 160 and lines 22 to 24 of the module being debugged:
DBG> TYPE 160, 22:24 module COBOLTEST 160: START-IT-PARA. module COBOLTEST 22: 02 SC2V2 PIC S99V99 COMP VALUE 22.33. 23: 02 SC2V2N PIC S99V99 COMP VALUE -22.33. 24: 02 CPP2 PIC PP99 COMP VALUE 0.0012. DBG> |
You can display all the source lines of a module by specifying a range of line numbers starting from 1 and ending at a number equal to or greater than the largest line number in the module.
After displaying a source line, you can display the next line in that module by entering a TYPE command without a line number---that is, by entering a TYPE command and then pressing the Return key. For example:
DBG> TYPE 160 module COBOLTEST 160: START-IT-PARA. DBG> TYPE module COBOLTEST 161: MOVE SC1 TO ES0. DBG> |
You can then display the next line and successive lines by entering the TYPE command repeatedly, which lets you read through your code one line at a time.
To display source lines in an arbitrary module of your program, specify the module name with the line numbers. Use standard pathname notation---that is, first specify the module name, then a backslash (\), and finally the line numbers (or the range of line numbers) without intervening spaces. For example, the following command displays line 16 of module TEST:
DBG> TYPE TEST\16 |
If you specify a module name with the TYPE command, the module must be set. Use the SHOW MODULE command to determine whether a particular module is set. Then use the SET MODULE command, if necessary (see Section 5.2).
If you do not specify a module name with the TYPE command, the debugger displays source lines for the module in which execution is currently paused by default---that is, the module associated with the PC scope. If you have specified another scope with the SET SCOPE command, the debugger displays source lines in the module associated with the specified scope.
In screen mode, the output of a TYPE command updates the current source display (see Section 7.2.6).
After displaying source lines at various locations in your program, you
can redisplay the line at which execution is currently paused by
pressing KP5.
6.4 Displaying Source Code by Specifying Code Address Expressions
The EXAMINE/SOURCE command enables you to display the source line corresponding to a code address expression. A code address expression denotes the address of a machine-code instruction and, therefore, must be one of the following:
You cannot specify a variable name with the EXAMINE/SOURCE command, because a variable name is associated with data, not with instructions.
When you use the EXAMINE/SOURCE command, the debugger evaluates the address expression to obtain a memory address, determines which compiler-assigned line number corresponds to that address, and then displays the source line designated by the line number.
For example, the following command line displays the source line associated with the address (declaration) of routine SWAP:
DBG> EXAMINE/SOURCE SWAP module MAIN 47: procedure SWAP(X,Y: in out INTEGER) is DBG> |
If you specify a line number that is not associated with an instruction, the debugger issues a diagnostic message. For example:
DBG> EXAMINE/SOURCE %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> |
When using the EXAMINE/SOURCE command with a symbolic address expression (a line number, label, or routine), you might need to set the module in which the entity is defined, unless that module is already set. Use the SHOW MODULE command to determine whether a particular module is set. Then, if necessary, use the SET MODULE command (see Section 5.2).
The command EXAMINE/SOURCE .%PC displays the source line corresponding to the current PC value (the line that is about to be executed). For example:
DBG> EXAMINE/SOURCE .%PC module COBOLTEST 162: DISPLAY ES0. DBG> |
Note the use of the contents-of operator (.), which specifies the contents of the entity that follows the period. If you do not use the contents-of operator, the debugger tries to find a source line for the PC rather than for the address currently stored in the PC:
DBG> EXAMINE/SOURCE %PC %DEBUG-W-NOSRCLIN, no source line for address 7FFF005C DBG> |
The following example shows the use of a numeric path name (1\) to display the source line at the PC value one level down the call stack (at the call to the routine in which execution is paused):
DBG> EXAMINE/SOURCE .1\%PC |
In screen mode, the output of an EXAMINE/SOURCE command updates the current source display (see Section 7.2.6).
The debugger uses the EXAMINE/SOURCE command in the following contexts to display source code at the current PC value.
Keypad key 5 (KP5) is bound to the following debugger command sequence:
EXAMINE/SOURCE .%SOURCE_SCOPE\%PC; EXAMINE/INST .%INST_SCOPE\%PC |
This command sequence displays the source line and the instruction at which execution is currently paused in the current scope. Pressing KP5 enables you to quickly determine your debugging context.
The predefined source display SRC is an automatically updated display that executes the following built-in command every time the debugger interrupts execution and prompts for commands (see Section 7.4.1):
EXAMINE/SOURCE .%SOURCE_SCOPE\%PC |
Previous | Next | Contents | Index |