Compaq COBOL
User Manual


Previous Contents Index


Appendix C
Programming Productivity Tools

Various programming productivity tools can help you increase your productivity as a Compaq COBOL programmer. These include the following:

C.1 Compaq FUSE---an Integrated Development Environment (Tru64 UNIX)

Compaq FUSE is the Compaq integrated software development environment for UNIX workstations. Compaq FUSE is available in two variations: the Compaq FUSE base system, and FUSElite, a subset of Compaq FUSE (used for C program development), which is upgradable to the full base system.

Compaq FUSE supports basic software development activities including coding, building, debugging, performance analysis and code management. Some of the Compaq FUSE tools are layered on commonly used UNIX tools including make , prof , rcs , and sccs . The default integrated debugger is Ladebug Debugger. These Compaq FUSE tools provide easy-to-use Motif graphic interfaces, plus benefits achieved through integration with other Compaq FUSE tools and through extensions to the capabilities of the base tools.

Compaq FUSE also provides an integrated text editor with a Motif user interface as well as integrated emacs and vi . Other Compaq FUSE tools provide integrated static analysis and browsing capabilities, including program source cross-referencing and call-graph browsing.

Additional tools (such as the Code Manager, Profiler, and Compare---all based on standard UNIX utilities---and the Cross-Referencer and Call Graph Browser) are available with the Compaq FUSE base system.

The Compaq FUSE integration framework allows tools to invoke one another and trigger operations. Programming tasks are automated and streamlined, reducing some operations to a single mouse button click.

With Compaq FUSE you can:

See the Compaq FUSE documentation for additional, detailed information. <>

Technical Note

With certain COBOL programs in the Compaq FUSE environment a problem will manifest itself by displaying the wrong file in the Compaq FUSE Editor tool for certain COBOL items which are clicked on from the Cross-Referencer tool. This can only happen for COBOL programs with successive COPY statements where there are no intervening data item references or declarations. To work around this problem, insert an extra declaration between successive COPY statements in the DATA DIVISION as follows:


 COPY "LIBRARY-1". 
01 EXTRA-ITEM PIC X. 
 COPY "LIBRARY-2". 

You should also insert an extra reference to a data item between successive COPY statements in the PROCEDURE DIVISION as follows:


 DISPLAY "TEST 7". 
 COPY "LIBRARY-1". 
 move 1 to extra-item. 
 COPY "LIBRARY-2". 

<>

C.2 Debugging Tools for Compaq COBOL Programs

This appendix includes representative debugging sessions that demonstrate debugger features for both the OpenVMS Debugger and the Tru64 UNIX Ladebug Debugger. These tools are source-level, symbolic debuggers that support Compaq COBOL data types and use.

Both the OpenVMS Debugger and the Tru64 UNIX Ladebug Debugger let you:

The debugging examples in Section C.3 and Section C.4 focus on a sample program, shown in Example C-1. One common program has been used, to emphasize the portability of Compaq COBOL.

As you read the debugging sections that follow, refer to the code in Example C-1 to identify source lines.

The program, TESTA, accepts a character string from the terminal and passes it to contained program TESTB. TESTB reverses the character string and returns it (and its length) to TESTA.

Example C-1 Source Code Used in the Sample Debug Sessions

module TESTA 
     1: IDENTIFICATION DIVISION. 
     2: PROGRAM-ID.  TESTA. 
     3: DATA DIVISION. 
     4: WORKING-STORAGE SECTION. 
     5:    01  TESTA-DATA        GLOBAL. 
     6:        02   LET-CNT      PIC 9(2)V9(2). 
     7:        02   IN-WORD      PIC X(20). 
     8:        02   DISP-COUNT   PIC 9(2). 
     9: PROCEDURE DIVISION. 
    10: BEGINIT. 
    11:     DISPLAY "ENTER WORD:". 
    12:     MOVE SPACES TO IN-WORD. 
    13:     ACCEPT IN-WORD. 
    14:     CALL "TESTB" USING IN-WORD LET-CNT. 
    15:     PERFORM SHOW-IT. 
    16:     STOP RUN. 
    17: SHOW-IT. 
    18:     DISPLAY IN-WORD. 
    19:     MOVE LET-CNT TO DISP-COUNT. 
    20:     DISPLAY DISP-COUNT " CHARACTERS". 
    21: IDENTIFICATION DIVISION. 
    22: PROGRAM-ID.  TESTB    INITIAL. 
    23: DATA DIVISION. 
    24: WORKING-STORAGE SECTION. 
    25:    01  SUB-1  PIC 9(2) COMP. 
    26:    01  SUB-2  PIC S9(2)  COMP-3. 
    27:    01  HOLD-WORD. 
    28:        03      HOLD-CHAR PIC X OCCURS 20 TIMES. 
    29:    01  HOLD-CHARS-REHOLD-WORD. 
    30:        03  CHARS PIC X(20). 
    31: LINKAGE SECTION. 
    32:    01  TEMP-WORD. 
    33:        03  TEMP-CHAR  PIC X OCCURS 20 TIMES. 
    34:    01  TEMP-CHARS REDEFINES TEMP-WORD. 
    35:        03  CHARS PIC X(20). 
    36:    01  CHARCT  PIC 99V99. 
    37: PROCEDURE DIVISION USING TEMP-WORD, CHARCT. 
    38: STARTUP. 
    39:     IF TEMP-WORD = SPACES 
    40:         MOVE 0 TO CHARCT 
    41:         EXIT PROGRAM. 
    42:     MOVE SPACES TO HOLD-WORD. 
    43:     PERFORM LOOK-BACK  VARYING SUB-1 FROM 20 BY -1 
    44:         UNTIL TEMP-CHAR (SUB-1) NOT = SPACE. 
    45:     MOVE SUB-1 TO CHARCT. 
    46:     PERFORM MOVE-IT    VARYING SUB-2 FROM 1 BY 1   UNTIL SUB-1 = 0. 
    47:     MOVE HOLD-WORD TO TEMP-WORD. 
    48: MOVE-IT. 
    49:     MOVE TEMP-CHAR (SUB-1) TO HOLD-CHAR (SUB-2). 
    50:     SUBTRACT 1 FROM SUB-1. 
    51: LOOK-BACK. 
    52:     EXIT. 
    53: END PROGRAM TESTB. 
    54: END PROGRAM TESTA. 

C.3 Ladebug Debugger (Tru64 UNIX)

The Ladebug Debugger is used to debug Compaq COBOL programs on the Tru64 UNIX operating system.

This section provides a representative debugging session that is designed to demonstrate the use of debugger features. For complete reference information on the Ladebug Debugger, you should refer to the Ladebug Debugger Manual in the Tru64 UNIX operating system documentation set. Online help is immediately available to you during a debugging session when you type help command at the debugger prompt (ladebug) . Additional information about the flags shown in this section is available in the man page. For example, you can type man cobol , and page to the appropriate topic to read information about the flags ( -g , -o ) used at the beginning of the example in this section.

  1. To begin this example you compile a Compaq COBOL program consisting of the single compilation unit named TESTA.


    % cobol -g -o testa testa.cob
    cobol: Warning: file not optimized; use -g3 for debug with optimize
    %
    

    The -g switch on the compiler command causes the compiler to write the debugger symbol table associated with the program into the executable program.
    Normally, the compiler turns off optimization when you specify -g and gives a warning to that effect. To debug your program with full optimization turned on, use the -g3 switch.

  2. The ladebug command starts the session. You provide your program name as a parameter (argument) to the command. After the debugger reads in your program's symbol table, it returns control with its prompt, (ladebug) .


    % ladebug testa
    Welcome to the Ladebug Debugger Version 2.0.8 eft
    ------------------ 
    object file name: testa 
    Reading symbolic information ...done
    (ladebug)
    

  3. Set a breakpoint. In this case, you wish to break at line 43 of your program.


    (ladebug) stop at 43
    [#2: stop at "testa.cob":43 ]
    

  4. Begin execution with the run command. The debugger starts program TESTA, prompts for a keyboard entry, and waits for a response.


    (ladebug) run
     ENTER WORD
     
    

  5. Enter the word to be reversed. Execution continues until the image reaches the breakpoint at line 43 of the contained program.


    abc
    [2] stopped at [TESTB:43 0x120001aa4]
         43     PERFORM LOOK-BACK  VARYING SUB-1 FROM 20 BY -1
    

  6. Set two breakpoints. You can give the debugger a list of commands to execute at breakpoints; the commands are entered in braces ({}).


    (ladebug) stop at 47 
    [#2: stop at "testa.cob":47 ]
    (ladebug) when at 50 { print chars of hold-chars; print SUB-1; cont; } 
    [#3: when at "testa.cob":50 { print CHARS of HOLD-CHARS; print SUB-1; ; cont ; } ]
    

  7. Display the active breakpoints.


    (ladebug) status 
    #1 PC==0x120001e14 in testa "testa.cob":2 { break }   
    #2 PC==0x120001ba4 in TESTB "testa.cob":47 { break } 
    #3 PC==0x120001c1c in TESTB "testa.cob":50          
       { ; print CHARS of HOLD-CHARS; print SUB-1; ; cont ; ; } 
    

  8. Use the list command to display the source lines where you set breakpoints.


    (ladebug) list 43,50
         43     PERFORM LOOK-BACK  VARYING SUB-1 FROM 20 BY -1
         44         UNTIL TEMP-CHAR (SUB-1) NOT = SPACE.
         45     MOVE SUB-1 TO CHARCT.
         46     PERFORM MOVE-IT    VARYING SUB-2 FROM 1 BY 1   UNTIL SUB-1 = 0.
         47     MOVE HOLD-WORD TO TEMP-WORD.
         48 MOVE-IT.
         49     MOVE TEMP-CHAR (SUB-1) TO HOLD-CHAR (SUB-2).
         50     SUBTRACT 1 FROM SUB-1.
    

  9. Set a tracepoint at line 15 of TESTA.


    (ladebug) trace at 15
    [#3: trace at "testa.cob":15 ]
    

  10. Set a watchpoint on the data item DISP-COUNT. When an instruction tries to change the contents of DISP-COUNT, the debugger returns control to you.


    (ladebug) stop disp-count of testa-data
    [#4: stop if DISP-COUNT of TESTA-DATA changes ]
    

  11. Execution resumes with the cont command. Each time line 50 in TESTB executes, the debugger executes the command list associated with this line; it displays the contents of HOLD-CHARS and SUB-1, then resumes execution. Finally, the debugger returns control to the user when the breakpoint at line 47 is reached.


    (ladebug) cont 
    [3] when [TESTB:50 0x120001c1c] 
    "c                   "
    3
    [3] when [TESTB:50 0x120001c1c] 
    "cb                  "
    2
    [3] when [TESTB:50 0x120001c1c] 
    "cba                 "
    1
    [2] stopped at [TESTB:47 0x120001ba4] 
         47     MOVE HOLD-WORD TO TEMP-WORD.
    

  12. Examine the contents of SUB-1.


    (ladebug) whatis sub-1
     unsigned short SUB-1
    (ladebug) print sub-1
    0
    

  13. Deposit the value --42 into data item SUB-2.


    (ladebug) whatis sub-2
     pic s99 usage comp-3 SUB-2
    (ladebug) assign sub-2=-42
    

  14. Examine the contents of SUB-2.


    (ladebug) print sub-2
    -42
    

  15. Examine the contents of CHARCT, whose picture is 99V99.


    (ladebug) whatis charct
     pic 99v99 usage display charct
    (ladebug) print charct
      3.00
    

  16. Deposit a new value into CHARCT.


    (ladebug) assign charct=15.95
    

  17. CHARCT now contains the new value.


    (ladebug) print charct
     15.95
    

  18. You can examine any character of a subscripted data item by specifying the character position. The following EXAMINE command accesses the second character in TEMP-CHAR.


    (ladebug) print temp-char of temp-word(2)
     "b"
    

  19. You can qualify data names in debug commands as you can in Compaq COBOL. For example, if you examine IN-WORD while you debug your program, you can use the following Ladebug Debugger command:


    (ladebug) print in-word of testa-data
     "abc                 "
    

  20. Restore CHARCT to its original value.


    (ladebug) assign charct=3.00
    

  21. Resume execution with the cont command. The program TESTA displays the reversed word. When the image reaches line 19 in TESTA, the debugger detects that an instruction changed the contents of DISP-COUNT. Because you set a watchpoint on DISP-COUNT, the debugger displays the old and new values, then returns control to you.


    (ladebug) cont
    [3] [calling testa from main cob_main.c:253 0x3ff8181f054] 
     cba
    [4] The value of DISP-COUNT of TESTA-DATA was changed in testa, 
        before entering cob_acc_display
            Old value =   0
            New value =   3
    [4] stopped at [cob_acc_display:349 0x3ff81808744] 
    (Cannot find source file cob_accdis.c) 
    

    Note that the Ladebug Debugger "watch" command shown here ( stop disp-count of testa-data ) does not stop immediately at the point when the value of the watched variable changes. In this example, the debugger takes control at the first procedure call or return after the value of the watched variable changes. For more information on the behavior of Ladebug Debugger watch , see the Ladebug Debugger Manual.

  22. To see the executable's current location, use the where command. Then, set the debugger file scope back to the main COBOL program, and stop at a specified line number in that file.


    (ladebug) where
    >0  0x3ff81808744 in cob_acc_display() cob_accdis.c:349
    #1  0x120001fbc in testa() testa.cob:20
    #2  0x3ff8181f054 in main() cob_main.c:253
    (ladebug) file testa.cob
    (ladebug) stop at 20
    [#6: stop at "testa.cob":20 ]
    

  23. Resume execution with the cont command. TESTA executes its final display. The debugger regains control when STOP RUN executes.


    (ladebug) cont
     03 CHARACTERS
    Thread has finished executing
    

  24. At this point you end the session with the q command.


    (ladebug) q                                        <>
    

C.4 OpenVMS Debugger (OpenVMS)

This section provides an introduction to using the OpenVMS debugger with Compaq COBOL programs. It includes the following:

For complete reference information on the OpenVMS debugger, see the OpenVMS Debugger Manual in the OpenVMS documentation set. Online help is immediately available to you during a debugging session when you type the HELP command at the debugger prompt (DBG>).

C.4.1 Notes on Compaq COBOL Support

In general, the OpenVMS debugger supports the data types and operators of Compaq COBOL and other debugger-supported languages. However, there are important language-specific limitations. (To get information about the supported data types and operators for a language, type the HELP LANGUAGE command at the DBG\> prompt.)

The debugger shows source text included in a program with the COBOL COPY file statement or the COPY module of library statement. However, the debugger does not show text which was created with the COPY REPLACING or REPLACE statement, or included by the COPY text FROM DICTIONARY statement.

The debugger cannot show the original source lines associated with the code for a REPORT section. You can see the DATA SECTION source lines associated with a report, but no source lines are associated with the compiled code that generates the report.

C.4.2 Notes on Debugging Optimized Programs

The Compaq COBOL compiler is a highly optimizing compiler. Several of the optimizations it performs, such as instruction scheduling and label deletion, can cause unexpected behavior in the OpenVMS Debugger.

Instruction scheduling can make the debugger appear to execute statements out of order. A single COBOL source statement can often result in several machine instructions. A RISC architecture machine, like the Alpha processor, can start working on a new instruction every machine cycle, but not all instructions can complete within one machine cycle. If the output from one machine instruction is used as the input to a subsequent machine instruction, the machine cannot begin processing the second instruction until it has finished processing the first. In many cases an entirely separate instruction can execute in parallel with the first instruction to perform a related computation.

During instruction scheduling, instructions are reordered to minimize waiting time. As a result an instruction resulting from a subsequent COBOL statement can be scheduled in the middle of (or even before) a sequence of instructions from a preceding statement. This reordering NEVER changes the meaning of your program, but it can make your program's execution in the debugger seem incorrect. The most common symptom of instruction scheduling is that the pointer in the debugger source window jumps back and forth between lines when you use the debugger STEP command.

When the compiler performs label deletion, it deletes paragraph and section labels that you do not explicitly reference in your source program. This prevents you from setting breakpoints on the affected labels which can make the analysis and optimization of your program more difficult.

Because of these and other Compaq COBOL compiler optimizations, Compaq recommends that you use the /NOOPTIMIZE qualifier in conjunction with the /DEBUG qualifier when you are debugging your COBOL programs. Using /NOOPTIMIZE qualifier disables most of the Compaq COBOL optimizations. In particular it suppresses most instruction scheduling and all label deletion optimizations.

The following OpenVMS Alpha debugging session does not show the location of program errors; it is designed to show only the use of debugger features.

  1. The following example shows how to compile and link a Compaq COBOL program consisting of a single compilation unit named TESTA.


    $ COBOL/DEBUG/NOOPTIMIZE TESTA
    $ LINK/DEBUG TESTA
    

    The /DEBUG qualifier on the COBOL command causes the compiler to write the debug symbol records associated with TESTA into the object module, TESTA.OBJ. These records allow you to use the names of variables and other symbols declared in TESTA in debugger commands. (If your program has several compilation units, you must compile each unit that you want to debug with the /DEBUG qualifier.)
    The /NOOPTIMIZE qualifier on the COBOL command disables default optimization for debugging. Because Compaq COBOL is, by default, a highly optimizing compiler, you will notice unusual and confusing program execution when you step through an optimized program with the debugger.
    The /DEBUG qualifier on the LINK command causes the linker to include all symbol information that is contained in TESTA.OBJ in the executable image. The qualifier also causes the image activator to start the debugger at run time. (If your program has several object modules, you might need to specify other modules in the LINK command.)

  2. The RUN command starts the session. If you compile and link the program with /DEBUG, you do not need to use the /DEBUG qualifier in the RUN command.
    When you give the RUN command, the debugger displays its standard header, showing that the default language is COBOL and the default scope and module are your main program. The debugger returns control with the prompt, DBG>.


    $ RUN TESTA
                  OpenVMS Alpha DEBUG Version V7.1-000
     
    %DEBUG-I-INITIAL, Language: COBOL, Module: TESTA
    %DEBUG-I-NOTATMAIN, type GO to get reach MAIN program
    DBG>
    

  3. Use the GO command to get to the start of the main program.


    DBG> GO 
    break at routine TESTA
        11:     DISPLAY "ENTER WORD"
    

  4. Set a breakpoint.


    DBG> SET BREAK %LINE 43
    

  5. Begin execution with the GO command. The debugger displays the execution starting point, and the image continues until TESTA displays its prompt and waits for a response.


    DBG> GO
    ENTER WORD:
    

  6. Enter the word to be reversed. Execution continues until the image reaches the breakpoint at line 43 of the contained program.


    abc
    break at TESTA\TESTB\%LINE 43
        43:        PERFORM LOOK-BACK  VARYING SUB-1 FROM 20 BY -1
    

  7. Set two breakpoints. When the debugger reaches line 50 of TESTB, it executes the commands in parentheses, displays the two data items, and resumes execution.


    DBG> SET BREAK %LINE 47
    DBG> SET BREAK %LINE 50 DO (EXAMINE HOLD-CHARS;EXAMINE SUB-1;GO)
    

  8. Display the active breakpoints.


    DBG> SHOW BREAK
    breakpoint at TESTA\TESTB\%LINE 43 
    breakpoint at TESTA\TESTB\%LINE 47 
    breakpoint at TESTA\TESTB\%LINE 50 
       do (EXAMINE HOLD-CHARS;EXAMINE SUB-1;GO)
    

  9. Use the TYPE command to display the source lines where you set breakpoints.


    DBG> TYPE 43:50
    module TESTA
        43:     PERFORM LOOK-BACK  VARYING SUB-1 FROM 20 BY -1
        44:         UNTIL TEMP_CHAR (SUB-1) NOT = SPACE.
        45:     MOVE SUB-1 TO CHARCT.
        46:     PERFORM MOVE-IT   VARYING SUB-2 FROM 1 BY 1   UNTIL SUB-1 = 0.
        47:     MOVE HOLD-WORD TO TEMP-WORD.
        48: MOVE-IT.
        49:     MOVE TEMP-CHAR (SUB-1)  TO HOLD-CHAR (SUB-2).
        50:     SUBTRACT 1 FROM SUB-1.
    

  10. Set a tracepoint at line 15 of TESTA.


    DBG> SET TRACE %LINE 15
    

  11. Set a watchpoint on the data item DISP-COUNT. When an instruction tries to change the contents of DISP-COUNT, the debugger returns control to you.


    DBG> SET WATCH DISP-COUNT
    DEBUG-I-WPTTRACE, non-static watchpoint, tracing every instruction
    

  12. Execution resumes with the GO command. Before line 50 in TESTB executes, the debugger executes the contents of the DO command entered at step 7. It displays the contents of HOLD-CHARS and SUB-1, then resumes execution.


    DBG> GO
    break at TESTA\TESTB\%LINE 50
        50:        SUBTRACT 1 FROM SUB-1.
    TESTA\TESTB\HOLD-CHARS: 
        CHARS:            "c                   "
    TESTA\TESTB\SUB-1:         3
    break at TESTA\TESTB\%LINE 50
        50:        SUBTRACT 1 FROM SUB-1.
    TESTA\TESTB\HOLD-CHARS 
        CHARS:            "cb                  "
    TESTA\TESTB\SUB-1:         2
    break at TESTA\TESTB\%LINE 50
        50:        SUBTRACT 1 FROM SUB-1.
    TESTA\TESTB\HOLD-CHARS
        CHARS:            "cba                 "
    TESTA\TESTB\SUB-1:         1
    break at TESTA\TESTB\%LINE 47
        47:        MOVE HOLD-WORD TO TEMP-WORD.
    DBG> 
    

  13. Examine the contents of SUB-1.


    Previous Next Contents Index