Page 1 of 1

The flow of control in program proceeded beyond last line

PostPosted: Sat Dec 31, 2011 10:25 pm
by Lakshmimuthu
Hi,
Some logic missed in program or some problem.
Please help me to resolve the abend U4038 in my cobol program. Program compilation was successfull but while running the program U4038 abend occured.
Following is the error message displayed in the spool with the compile and offset details.

"The flow of control in program proceeded beyond the last line From compile unit entry point"

Program:

IDENTIFICATION DIVISION.
PROGRAM-ID. EMPPARM.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT EMPLOYEE-FILE ASSIGN TO EMPIN.

SELECT DEPARTMENT-FILE ASSIGN TO DEPTMAST
ORGANIZATION IS INDEXED
ACCESS MODE IS RANDOM
RECORD KEY IS DEPARTMENT-ID.

SELECT OUTPUT-FILE ASSIGN TO OUTFILE.

DATA DIVISION.
FILE SECTION.
FD EMPLOYEE-FILE.
COPY EMPREC.
FD DEPARTMENT-FILE.
COPY DEPTREC.
FD OUTPUT-FILE.
01 OUTPUT-RECORD PIC X(80).

WORKING-STORAGE SECTION.
01 FLAGS-AND-SWITCHES.
05 END-OF-FILE PIC XXX VALUE 'NO'.
88 AT-END-OF-EMPLOYEE-FILE VALUE 'YES'.
88 NOT-AT-END-OF-EMPLOYEE-FILE VALUE 'NO'.
01 WS-PARA-NAME PIC X(20).

LINKAGE SECTION.
*01 JCL-PARM-DATA.
* 05 PARM-LENGTH PIC S9(04) COMP.

PROCEDURE DIVISION.
0000-MAIN.
MOVE "0000-MAIN" TO WS-PARA-NAME
PERFORM 1000-HOUSEKEEPING THRU
1000-HOUSEKEEPING-EXIT
PERFORM 2000-PROCESS-EMPLOYEE THRU
2000-PROCESS-EMPLOYEE-EXIT
UNTIL AT-END-OF-EMPLOYEE-FILE
PERFORM 3000-CLEANUP THRU
3000-CLEANUP-EXIT
STOP RUN.

1000-HOUSEKEEPING.
MOVE '1000-HOUSEKEEPING' TO WS-PARA-NAME

OPEN INPUT EMPLOYEE-FILE
INPUT DEPARTMENT-FILE
OUTPUT OUTPUT-FILE.
1000-HOUSEKEEPING-EXIT. EXIT.

2000-PROCESS-EMPLOYEE.
MOVE '2000-PROCESS-EMPLOYEE' TO WS-PARA-NAME

PERFORM 2300-READ-EMP-REC THRU
2300-READ-EMP-REC-EXIT
PERFORM 2600-LOOKUP-DEPT THRU
2600-LOOKUP-DEPT-EXIT
PERFORM 2800-WRITE-OUTPUT THRU
2800-WRITE-OUTPUT-EXIT.
2000-PROCESS-EMPLOYEE-EXIT. EXIT.

2300-READ-EMP-REC.
MOVE '2300-READ-EMP-REC' TO WS-PARA-NAME

READ EMPLOYEE-FILE
AT END
SET AT-END-OF-EMPLOYEE-FILE TO TRUE
GO TO 2800-WRITE-OUTPUT-EXIT
2300-READ-EMP-REC-EXIT. EXIT.
2600-LOOKUP-DEPT.
MOVE '2600-LOOKUP-DEPT' TO WS-PARA-NAME

MOVE DEPT-ID TO DEPARTMENT-ID
READ DEPARTMENT-FILE
INVALID KEY
DISPLAY 'DEPT NOT FOUND'
GO TO 2800-WRITE-OUTPUT-EXIT EXIT
END-READ
READ EMPLOYEE-FILE NEXT RECORD
AT END
SET AT-END-OF-EMPLOYEE-FILE TO TRUE
END-READ.
2600-LOOKUP-DEPT-EXIT. EXIT.
2800-WRITE-OUTPUT.

MOVE '2800-WRITE-OUTPUT' TO WS-PARA-NAME
STRING
EMPLOYEE-NAME DELIMITED BY SIZE
' ' DELIMITED BY SIZE
DEPARTMENT-NAME DELIMITED BY SIZE
INTO OUTPUT-RECORD
WRITE OUTPUT-RECORD.
2800-WRITE-OUTPUT-EXIT. EXIT.

3000-CLEANUP.
MOVE '2800-WRITE-OUTPUT' TO WS-PARA-NAME

CLOSE EMPLOYEE-FILE
CLOSE DEPARTMENT-FILE
CLOSE OUTPUT-FILE.
3000-CLEANUP-EXIT. EXIT.






JCL:

//MUTHULA JOB (ABCDE),'QUASAR CHUNA',MSGCLASS=Y,
// MSGLEVEL=(1,1),CLASS=A,NOTIFY=&SYSUID,REGION=200M
//*-------------------------------------------------
//JOBLIB DD DSN=MUTHULA.DEMO.LOADLIB,DISP=SHR <== Load Library
//STEP01 EXEC PGM=EMPPARM <== Load Module Name
//EMPIN DD DSN=AGY0157.EMPLOYEE.DATA,DISP=SHR
//DEPTMAST DD DSN=AGY0157.DEPT.MASTER.DATA,DISP=SHR
//OUTFILE DD DSN=MUTHULA.SEQ.EMP.OUT,
// DISP=(NEW,CATLG,DELETE),
// SPACE=(TRK,(10,10,01)),
// DCB=(LRECL=80,RECFM=FB,BLKSIZE=800),
// UNIT=SYSDA
//SYSPRINT DD SYSOUT=*
//SYSOUT DD SYSOUT=*
//


Let me know if i have done something irrelevant.

Re: The flow of control in program proceeded beyond last lin

PostPosted: Sat Dec 31, 2011 10:39 pm
by Robert Sample
2300-READ-EMP-REC.
    MOVE '2300-READ-EMP-REC' TO WS-PARA-NAME

    READ EMPLOYEE-FILE
    AT END
        SET AT-END-OF-EMPLOYEE-FILE TO TRUE
        GO TO 2800-WRITE-OUTPUT-EXIT
This code is wrong. When it has read the last EMPLOYEE-FILE record, it jumps to 2800-WRITE-OUTPUT-EXIT. Since the 2800-WRITE-OUTPUT paragraph is not active in a PERFORM at this time, control falls through the EXIT to the next paragraph, then the next, after which the abend is generated as you've gone through the last line of code and there's no other code to execute.

Note how much more readable the code is when put in the Code tag rather than just pasted in your post.

Re: The flow of control in program proceeded beyond last lin

PostPosted: Sat Dec 31, 2011 11:44 pm
by BillyBoyo
Lakshmimuthu wrote:[...]
         2600-LOOKUP-DEPT.
             MOVE '2600-LOOKUP-DEPT' TO  WS-PARA-NAME
 
             MOVE DEPT-ID TO DEPARTMENT-ID
             READ DEPARTMENT-FILE
               INVALID KEY
                  DISPLAY 'DEPT NOT FOUND'
               GO TO 2800-WRITE-OUTPUT-EXIT  EXIT
             END-READ
             READ EMPLOYEE-FILE NEXT RECORD
               AT END
               SET AT-END-OF-EMPLOYEE-FILE TO TRUE
             END-READ.
         2600-LOOKUP-DEPT-EXIT. EXIT.


You have another one as well. If the DEPT is not found, it'll hit this one before the end-of-file anyway. Also you seem to have a spare "EXIT" statement.

You are also reading the employee-file again here, so you will be missing out records. If that is deliberate, due to the structure of the data (a sub-record you don't need, for instance) then you should 1) document it and 2) check that the record you are ignoring is the one you expect to ignore, else you will be ignoring the wrong thing and/or processing a file which has errors in it.

        3000-CLEANUP.
            MOVE '2800-WRITE-OUTPUT' TO  WS-PARA-NAME

            CLOSE EMPLOYEE-FILE
            CLOSE DEPARTMENT-FILE
            CLOSE OUTPUT-FILE.
        3000-CLEANUP-EXIT. EXIT.




In the above the 2800-WRITE-OUTPUT is obviously wrong as well.

You have a problem with the structure of your program.

Re: The flow of control in program proceeded beyond last lin

PostPosted: Sun Jan 01, 2012 2:44 pm
by NicC
You also seem to have NO error checking whilst opening/reading files.