Abend0C4 on a MOVE from a file following the READ of a variable length record.
The user has a COBOL program that has been running successfully before a change was made in his runtime setup. Now he gets an Abend0C4 on a MOVE from the File Definition layout to some other area. This could be after changing the Language Environment release, installing maintenance, or recompiling the program (with or without changes).
This happens when these 2 reasons are combined.
A) The program is moving a fixed area from the FD that is longer than the actual record, which causes addressing to go out of the variable file block and buffer . (This works as long as the area addressed belongs to the program, even though excess data is moved.)
B) Changes to the runtime environment may cause file buffers to be allocated in different storage locations. This may cause the program moving an area that is larger than the record to attempt to address storage that is not available to that program.
Enterprise COBOL with LE z/OS. This can also occur on other S390 platforms under VM and VSE/ESA and with older COBOL compilers and operating systems. It is a problem involving the user coding technique.
Resolving the problem
There are at least three permanent solutions for this situation listed below:
1) If the data needs to be MOVEd right after the READ with no intervening logic, coding READ...INTO instead of MOVE can circumvent the ABEND0C4. This is because a READ ... INTO will move the actual number of bytes in the record just read.
for a discussion of possible performance issues involving READ...INTO coding in some cases.
2) Define an 01 under the FD for every possible record length that is in the file, determine which one is right based on the content of the record and move the 01 of the right length.
3) However, if there is intervening logic or you need the actual record length you will need to review the information about Format 3 of the RECORD clause in the COBOL Language Reference manual. Format 3 is the most robust solution. This way you'll know the true record length.
To define the INPUT file as truly Variable, you will need to set up at least one of the following: a RECORD IS VARYING FROM n TO n in the FD; a RECORD CONTAINS n TO n clause in the FD; and/or multiple 01 level definitions in the FD.
The RECORD IS VARYING clause is necessary to capture the length of a record read.
Here is a sample of a workaround for problems involving the MOVE of a variable record description that is longer that the actual record read. The sample below uses reference modification for the move. I have marked the code that should be considered with ====>'s
Consider the following section of a sample program:
INPUT OUTPUT SECTION.
SELECT INPUT-FILE ASSIGN TO INPUTFL.
BLOCK CONTAINS 0 RECORDS
RECORD IS VARYING IN SIZE FROM 1 TO 800
=======> DEPENDING ON WK-IN1-LENGTH.
01 INPUT-REC1 PIC X(800) .
01 INPUT-REC2 PIC X(270) .
01 INPUT-REC3 ..contains OCCURS DEPENDING ON...
=======> 05 WK-IN1-LENGTH PIC 9(5).
=======> 05 WK-AREA-LENGTH PIC 9(5).
01 WS-AREA PIC X(800).
OPEN INPUT INPUT-FILE
READ INPUT-FILE AT END ...
=======> MOVE INPUT-REC1 TO WS-AREA.
The MOVE just above may FAIL with Abend0C4 because it will move 800 bytes no matter what the true record length is.
WK-IN1-LENGTH will be loaded with the length of each record when it is read.
If the user captures the length of the data read, this type of coding will bypass any problem:
MOVE WK-IN1-LENGTH TO WK-AREA-LENGTH.
=======> MOVE INPUT-REC1(1:WK-IN1-LENGTH) TO
=======> WS-AREA (1:WK-AREA-LENGTH)
It it usually best to move from the longest record description and use reference modification to limit the size.
The move does not have to go to WORKING-STORAGE, but could be to an output file record area. The example above uses the DEPENDING ON clause. That is a safe thing to do. It is safer than relying on a byte or two near the beginning of each record to inform the program what the record length is.
Do not use negative subscripts to discover the record length in the RDW of RECFM=V records. That was never supported and no longer works with the supported compilers.
The topic Requesting Variable Length Format in the Enterprise COBOL Programming Guide, V4R2, (SC23-8529) also describes this situation.
|Software Development||COBOL for OS/390 & VM||Compile||VM/ESA||2.1, 2.2|
|Software Development||COBOL for VSE/ESA||Compile||VSE/ESA||1.1|