OpenVMS Debugger Manual


Previous Contents Index

5.4.2 Accessing Symbols in Shareable Images

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.

  1. Compile the shareable image. For example:


    $ CC/DEBUG/NOOPTIMIZE RESIDENTMODULE.C
    

  2. Link the shareable image using the /DSF qualifier. For example:


    $ LINK/NOTRACEBACK/SHAREABLE/SECTION_BINDING/DSF RESIDENTMODULE 
    

    See the OpenVMS Linker Utility Manual for information about linking the image.

  3. Create the installed resident image. See OpenVMS System Management Utilities Reference Manual: A--L for information about using the Install utility. See OpenVMS System Manager's Manual, Volume 2: Tuning, Monitoring, and Complex Systems for information about resident images.
  4. Compile the program that calls the resident image. For example:


    $ CC/DEBUG/NOOPTIMIZE TESTPROGRAM
    

  5. Create the executable image that calls the resident image. For example:


    $ LINK/DSF TESTPROGRAM
    

  6. Create a private copy of the resident image. For example:


    $ COPY SYS$LIBRARY:RESIDENTMODULE.EXE []RESIDENTMODULE.EXE
    

  7. Define a logical name that points to the private copy of the resident image. For example:


    $ DEFINE RESIDENTMODULE []RESIDENTMODULE
    

  8. Make sure that the .DSF file for the test program and the .DSF file for the resident module both reside in the same directory.
  9. Define DBG$IMAGE_DSF_PATH to point to the directory that contains the .DSF files.
  10. Invoke the debugger. For example:


    $ DEBUG/KEEP TESTPROGRAM
    

You should now have access to all debugging options for the executable and resident images.


Chapter 6
Controlling the Display of Source Code

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