Compaq COBOL
User Manual


Previous Contents Index

1.3.4.3 Accessing Input and Output Devices at Run Time

ACCEPT and DISPLAY statements may interact with the input and output devices by referring to them through the environment variables COBOL_INPUT and COBOL_OUTPUT, respectively. See Chapter 11 for more information.

1.3.4.4 Debugging Environment

Perhaps the most common qualifier added to the RUN command line is DEBUG. The form of the RUN command with DEBUG is as follows:

RUN [/[NO]DEBUG] file-spec

In the preceding syntax format file-spec is the name of the executable image to be run. A typical example would be:


$ RUN /DEBUG MYPROG

In this example, MYPROG is the name of the executable image to be run. You would specify the /DEBUG qualifier to invoke the OpenVMS Debugger if the image was not linked with it. You cannot use /DEBUG on images linked with the /NOTRACEBACK qualifier. If the image (in this case, MYPROG) was linked with the /DEBUG qualifier and you do not want the debugger to prompt you, use the /NODEBUG qualifier. The default action depends on whether or not the file was linked with the /DEBUG qualifier.

Note

Using the /DEBUG qualifier with the RUN command does not produce symbol table information if you did not specify the /DEBUG qualifier when you compiled and linked your program.

The following example executes the image MYPROG.EXE without invoking the debugger:


$ RUN MYPROG/NODEBUG 

See Appendix C for more information about debugging programs.

1.3.4.5 Interpreting Run-Time Messages

During execution, an image can generate a fatal error called an exception condition. When an exception condition occurs, the system displays a message. Run-time messages can also be issued by the OpenVMS Alpha operating system or by other utilities such as SORT. Other kinds of errors that can occur at run time include program run errors and run-time input/output errors.

Run-time messages have the following format:

%COB-s-ident, message-text

%COB

The program name of the Compaq COBOL Run-Time Library. This prefix indicates a run-time message.

s

The severity of the error. As with messages from the compiler and the linker, the severity indicator can be F (Fatal), E (Error), W (Warning), or I (Informational).

ident

The message identification. This is a descriptive abbreviation of the message text.

message-text

The run-time message. This portion may contain more than one line of output. A message generally provides you with enough information to determine the cause of the error so that you can correct it.

The following example shows a run-time message issued for an illegal divide:


%COB-E-DIVBY-ZER, divide by zero; execution continues 

Both the compiler and the OpenVMS Alpha Run-Time Library include facilities for detecting and reporting errors. You can use the OpenVMS Debugger and the traceback facility to help you locate errors that occur during program execution. For a description of Compaq COBOL run-time messages, use the HELP COBOL Run-Time Messages command.

Run-Time Messages

Faulty program logic can cause abnormal termination. If errors occur at run time, the Run-Time Library (RTL) displays a message with the same general format as system error messages. In addition, the system traceback facility displays a list of the routines that were active when the error occurred.

When an error occurs, TRACEBACK produces a symbolic dump of the active call frames. A call frame represents one execution of a routine. For each call frame, TRACEBACK displays the following information:

  1. The module name, (program-id)
  2. The routine name (program-id)
  3. The source listing line number where the error or CALL occurred
  4. Program-counter (PC) information

You can also use the OpenVMS Debugger to examine the machine code instruction. To do this, compile and link the program using the /DEBUG qualifier. When you run the program, you automatically enter the debugger. Once in the debugger, you could use the EXAMINE/INSTRUCTION command to examine the contents of the failed instruction. You could also use the debugger in screen mode, which would indicate where the error occurred.

For more information about the OpenVMS Debugger, refer to Appendix C and the OpenVMS Debugger Manual.

1.4 Program Run Messages

Incorrect or undesirable program results are usually caused by data errors or program logic errors. You can resolve most of these errors by desk-checking your program and by using a debugger.

1.4.1 Data Errors

Faulty or incorrectly defined data often produce incorrect results. Data errors can sometimes be attributed to one or more of the following actions:

In the following example, a program references the file incorrectly. The field described as P-YEARLY-AMT actually contains P-MONTHLY-AMT data, and vice versa.


01  PAY-RECORD. 
    03  P-NUMBER       PIC X(5). 
    03  P-WEEKLY-AMT   PIC S9(5)V99  COMP-3. 
    03  P-YEARLY-AMT   PIC S9(5)V99  COMP-3. 
    03  P-MONTHLY-AMT  PIC S9(5)V99  COMP-3. 
        . 
        . 
        . 
PROCEDURE DIVISION. 
ADD-TOTALS. 
    ADD P-MONTHLY-AMT TO TOTAL-MONTHLY-AMT. 
        . 
        . 
        . 

You can minimize record field position errors by writing your file and record descriptions in a library file and then using the COPY statement in your programs. On OpenVMS Alpha systems, you can also use the COPY FROM DICTIONARY statement.

Choosing your test data carefully can minimize faulty data problems. For instance, rather than using actual or ideal data, use test files that include data extremes.

Determining when a program produces incorrect results can often help your debugging effort. You can do this by maintaining audit counts (such as total master in = nnn, total transactions in = nnn, total deletions = nnn, total master out = nnn) and displaying the audit counts when the program ends. Using conditional compilation lines (see Section 1.3.2.7) in your program can also help you to debug it.

1.4.2 Program Logic Errors

When checking your program for logic errors, first examine your program for some of the more obvious bugs, such as the following:

1.4.3 Run-Time Input/Output Errors

An input/output error is a condition that causes an I/O statement to fail. These I/O errors are detected at run time by the I/O system. Each time an I/O operation occurs, the I/O system generates a two-character file status value. One way to determine the nature of an I/O error is to check a file's I/O status by using file status data items. (See the Compaq COBOL Reference Manual for a list of file status values.) See Chapter 7, Handling Input/Output Exception Conditions for additional information about I/O exception condition handling.

Checking a file's I/O status within a Declarative USE procedure or in an INVALID KEY imperative condition can help you determine the nature of an I/O error. For example:


FD  INDEXED-MASTER 
    ACCESS MODE IS DYNAMIC 
    FILE STATUS IS MASTER-STATUS 
    RECORD KEY IN IND-KEY. 
  . 
  . 
  . 
WORKING-STORAGE SECTION. 
01  MASTER-STATUS      PIC XX  VALUE SPACES. 
  . 
  . 
  . 
PROCEDURE DIVISION. 
  . 
  .                                                     
  . 
050-READ-MASTER. 
    READ INDEXED-MASTER 
      INVALID KEY PERFORM 100-CHECK-STATUS 
      GO TO 200-INVALID-READ. 
      . 
      . 
      . 
100-CHECK-STATUS. 
    IF MASTER-STATUS = "23" 
       DISPLAY "RECORD NOT IN FILE". 
    IF MASTER-STATUS = "24" 
       DISPLAY "BOUNDARY VIOLATION OR RELATIVE RECORD 
       NUMBER TOO LARGE". 
      . 
      . 
      . 

If your program contains a Declarative USE procedure for a file and an I/O operation for that file fails, the I/O system performs the USE procedure, but does not display an error message.

A Declarative USE procedure can sometimes avoid program termination. For example, File Status 91 indicates that the file is locked by another program; rather than terminate your program, you can perform other procedures and then try reopening the file. If program continuation is not desirable, the Declarative USE procedure can perform housekeeping functions, such as saving data or displaying program-generated diagnostic messages.

If you specify an INVALID KEY phrase for a file and the I/O operation causes an INVALID KEY condition, the I/O system performs the associated imperative statement and no other file processing for the current statement. The Declarative USE procedure (if any) is not performed. The INVALID KEY phrase processes I/O errors due to invalid key conditions only.

If you do not specify an INVALID KEY phrase but declare a Declarative USE procedure for the file, the I/O system performs the Declarative USE procedure and returns control to the program.

If a severe error occurs and you do not have a Declarative Use procedure, your program will terminate abruptly with a run-time diagnostic. For example, given a program that looks for AFILE.DAT and that file is missing:


cobrtl: severe: file AFILE.DAT not found 

In this case, program run ends because you have not handled the error with a Declarative Use procedure.

1.4.4 I/O Errors and RMS (OpenVMS)

I/O errors are detected by the I/O system, which (for OpenVMS Alpha systems) consists of Record Management Services (RMS) and the Run-Time Library (RTL). You can use the RMS special registers, which contain the primary and secondary RMS completion codes of an I/O operation, to detect errors. The RMS special registers are as follows:

RMS-STS
RMS-STV
RMS-FILENAME
RMS-CURRENT-STS
RMS-CURRENT-STV
RMS-CURRENT-FILENAME

Refer to the Compaq COBOL Reference Manual and the OpenVMS Record Management Services Reference Manual for more information about RMS special registers.

Examples 1-5 and 1-6 show how you can use RMS special registers to detect errors.

Example 1-5 Using RMS Special Registers to Detect Errors (OpenVMS)

IDENTIFICATION DIVISION. 
PROGRAM-ID. RMS-SPEC-REGISTERS. 
* 
* This program demonstrates the use of RMS special registers to 
* implement a different recovery for each of several errors with RMS files 
* 
ENVIRONMENT DIVISION. 
INPUT-OUTPUT SECTION. 
FILE-CONTROL. 
SELECT OPTIONAL EMP-FILE 
    ASSIGN TO "SYS$DISK:ART.DAT". 
SELECT REPORT-FILE 
    ASSIGN TO "SYS$OUTPUT". 
DATA DIVISION. 
FILE SECTION. 
FD      EMP-FILE 
        VALUE OF ID IS VAL-OF-ID. 
01      EMP-RECORD. 
        02       EMP-ID       PIC 9(7). 
        02       EMP-NAME     PIC X(15). 
        02       EMP-ADDRESS  PIC X(30). 
FD      REPORT-FILE           REPORT IS RPT. 
WORKING-STORAGE SECTION. 
01      VAL-OF-ID             PIC X(20). 
01      END-OF-FILE           PIC S9(9)  COMP VALUE EXTERNAL RMS$_EOF. 
01      BADNAME               PIC S9(9)  COMP VALUE EXTERNAL SS$_BADFILENAME. 
01      FILE-NOT-FOUND        PIC S9(9)  COMP VALUE EXTERNAL RMS$_FNF. 
01      DIR-NOT-FOUND         PIC S9(9)  COMP VALUE EXTERNAL RMS$_DNF. 
01      INV-DEVICE            PIC S9(9)  COMP VALUE EXTERNAL RMS$_DEV. 
01      INV-FILE-ID           PIC S9(9)  COMP VALUE EXTERNAL RMS$_IFI. 
01      RMS-ERR               PIC S9(9)  COMP VALUE EXTERNAL SHR$_RMSERROR. 
01      D-DATE                PIC 9(6). 
01      EOF-SW                PIC X. 
        88       E-O-F                   VALUE "E". 
        88       NOT-E-O-F               VALUE "N". 
01      VAL-OP-SW             PIC X. 
        88                    VALID-OP   VALUE "V". 
        88                    OP-FAILED  VALUE "F". 
01      OP                    PIC X. 
        88                    OP-OPEN    VALUE "O". 
        88                    OP-CLOSE   VALUE "C". 
        88                    OP-READ    VALUE "R". 
REPORT SECTION. 
RD      RPT     PAGE 26 LINES HEADING 1  FIRST DETAIL 5. 
01              TYPE IS PAGE HEADING. 
    02  LINE IS PLUS 1. 
        03      COLUMN 1    PIC X(16)    VALUE "Employee File on". 
        03      COLUMN 18   PIC Z9/99/99 SOURCE D-DATE. 
    02  LINE IS PLUS 2. 
        03      COLUMN 2    PIC X(5)     VALUE "emp  ". 
        03      COLUMN 22   PIC X(4)     VALUE "name". 
        03      COLUMN 42   PIC X(7)     VALUE "address". 
        03      COLUMN 70   PIC ZZ9      SOURCE PAGE-COUNTER. 
01      REPORT-LINE         TYPE IS DETAIL. 
    02  LINE IS PLUS 1. 
        03      COLUMN IS 1 PIC 9(7)     SOURCE EMP-ID. 
        03      COLUMN IS 20 PIC X(15)   SOURCE IS EMP-NAME. 
        03      COLUMN IS 42 PIC X(30)   SOURCE IS EMP-ADDRESS. 
PROCEDURE DIVISION. 
DECLARATIVES. 
USE-SECT SECTION. 
    USE AFTER STANDARD ERROR PROCEDURE ON EMP-FILE. 
CHECK-RMS-SPECIAL-REGISTERS. 
    SET OP-FAILED TO TRUE. 
    EVALUATE RMS-STS OF EMP-FILE           TRUE 
         WHEN (END-OF-FILE)                OP-READ 
                  SET VALID-OP TO TRUE 
                  SET E-O-F TO TRUE 
         WHEN (BADNAME)                    OP-OPEN 
         WHEN (FILE-NOT-FOUND)             OP-OPEN 
         WHEN (DIR-NOT-FOUND)              OP-OPEN 
         WHEN (INV-DEVICE)                 OP-OPEN 
                  DISPLAY     "File cannot be found or file spec is invalid" 
                  DISPLAY RMS-FILENAME OF EMP-FILE 
                  DISPLAY "Enter corrected file (cntrl-z to STOP RUN): " 
                              WITH NO ADVANCING 
                  ACCEPT VAL-OF-ID AT END STOP RUN END-ACCEPT 
         WHEN ANY                          OP-CLOSE 
                  CONTINUE   
         WHEN ANY                          RMS-STS OF EMP-FILE IS SUCCESS 
                  SET VALID-OP TO TRUE 
         WHEN OTHER 
                  IF RMS-STV OF EMP-FILE NOT = ZERO 
                  THEN 
                    CALL "LIB$STOP" USING 
                       BY VALUE RMS-STS OF EMP-FILE, 
                       BY VALUE RMS-STV OF EMP-FILE 
                  ELSE 
                      CALL "LIB$STOP" USING 
                       BY VALUE RMS-STS OF EMP-FILE 
                  END-IF 
    END-EVALUATE. 
END DECLARATIVES. 
MAIN-PROG SECTION. 
000-DRIVER. 
    PERFORM 100-INITIALIZE. 
    PERFORM WITH TEST AFTER UNTIL E-O-F 
        GENERATE REPORT-LINE 
        READ EMP-FILE 
    END-PERFORM 
    PERFORM 200-CLEANUP. 
    STOP RUN. 
100-INITIALIZE. 
    ACCEPT D-DATE FROM DATE. 
    DISPLAY "Enter file spec of employee file: " WITH NO ADVANCING. 
    ACCEPT VAL-OF-ID. 
    PERFORM WITH TEST AFTER UNTIL VALID-OP 
        SET VALID-OP TO TRUE 
        SET OP-OPEN TO TRUE 
        OPEN INPUT EMP-FILE 
        IF OP-FAILED 
        THEN 
            SET OP-CLOSE TO TRUE 
            CLOSE EMP-FILE 
        END-IF 
    END-PERFORM. 
    OPEN OUTPUT REPORT-FILE. 
    INITIATE RPT. 
    SET NOT-E-O-F TO TRUE. 
    SET OP-READ TO TRUE. 
    READ EMP-FILE. 
200-CLEANUP. 
    TERMINATE RPT. 
    SET OP-CLOSE TO TRUE. 
    CLOSE EMP-FILE REPORT-FILE. 
END PROGRAM RMS-SPEC-REGISTERS. 

Example 1-6 Using RMS-CURRENT Special Registers to Detect Errors (OpenVMS)

IDENTIFICATION DIVISION. 
PROGRAM ID. RMS-CURRENT-SPEC-REGISTERS. 
* 
* This program demonstrates the use of RMS-CURRENT special registers 
* to implement a single recovery for RMS file errors with multiple files 
* 
ENVIRONMENT DIVISION. 
INPUT-OUTPUT SECTION. 
FILE-CONTROL. 
SELECT FILE-1 
        ASSIGN TO "SYS$DISK:ART_1.DAT". 
SELECT FILE-2 
        ASSIGN TO "SYS$DISK:ART_2.DAT". 
SELECT FILE-3 
        ASSIGN TO "SYS$DISK:ART_3.DAT". 
DATA DIVISION. 
FILE SECTION. 
FD      FILE-1. 
01      FILE-1-REC. 
        02      F1-REC-FIELD    PIC 9(9). 
FD      FILE-2. 
01      FILE-2-REC. 
        02      F2-REC-FIELD    PIC 9(9). 
FD      FILE-3. 
01      FILE-3-REC. 
        02      F3-REC-FIELD    PIC 9(9). 
PROCEDURE DIVISION. 
DECLARATIVES. 
USE-SECT SECTION. 
        USE AFTER STANDARD EXCEPTION PROCEDURE ON INPUT. 
CHECK-RMS-CURRENT-REGISTERS. 
        DISPLAY "************** ERROR **************". 
        DISPLAY "Error on file: " RMS-CURRENT-FILENAME. 
        DISPLAY "Status Values:". 
        DISPLAY "      RMS-STS = " RMS-CURRENT-STS WITH CONVERSION. 
        DISPLAY "      RMS-STV = " RMS-CURRENT-STV WITH CONVERSION. 
        DISPLAY "***********************************". 
END DECLARATIVES. 
MAIN-PROG SECTION. 
MAIN-PARA. 
        OPEN INPUT FILE-1. 
        OPEN INPUT FILE-2. 
        OPEN INPUT FILE-3. 
        . 
        . 
        . 
        CLOSE FILE-1. 
        CLOSE FILE-2. 
        CLOSE FILE-3. 
        STOP RUN. 
END-PROGRAM RMS-CURRENT-SPEC-REGISTERS.                          <>

1.5 Using Program Switches

You can control program execution by defining switches in your Compaq COBOL program and setting them internally (from within the image) or externally (from outside the image). Switches exist as the environment variable COBOL_SWITCHES (on the Tru64 UNIX operating system) or the logical name COB$SWITCHES (on the OpenVMS Alpha operating system).

On OpenVMS Alpha systems, switches can be defined for the image, process, group, or system. <>

On Tru64 UNIX systems, switches can be defined for the image or process. <>

1.5.1 Setting and Controlling Switches Internally

To set switches from within the image, define them in the SPECIAL-NAMES paragraph of the ENVIRONMENT DIVISION and use the SET statement in the PROCEDURE DIVISION to specify switches ON or OFF, as in the following example:


ENVIRONMENT DIVISION. 
CONFIGURATION SECTION. 
SPECIAL-NAMES. 
    SWITCH 10 IS MY-SWITCH       
      ON IS SWITCH-ON       
      OFF IS SWITCH-OFF.   
    .     
    .     
    . 
PROCEDURE DIVISION. 
000-SET-SWITCH.     
    SET MY-SWITCH TO ON. 
    IF SWITCH-ON 
       THEN 
    DISPLAY "Switch 10 is on". 
    .     
    .     
    . 

To change the status of internal switches during execution, turn them on or off from within your program. However, be aware that this information is not saved between runs of the program.

Refer to the Compaq COBOL Reference Manual for more information about setting internal switches.


Previous Next Contents Index