COBOL sequential file reads succeed locally but produce garbled output in production
0 reputation · 31 Oct 2021, 01:09 UTC
0 reputation · 31 Oct 2021, 01:09 UTC
A COBOL program using sequential file I/O with ORGANIZATION IS SEQUENTIAL and ACCESS MODE SEQUENTIAL compiles and runs without file-status errors on a local ASCII-based runtime. When deployed to an EBCDIC production environment, the same executable or recompiled source opens, reads, and writes successfully (file status 00), yet alphanumeric fields contain unexpected byte values and numeric-edited fields display transposed decimal separators.
The FD defines USAGE DISPLAY alphanumeric and edited numeric fields. No CODE-SET clause or NATIONAL usage is specified. The local build runs on a Linux or Windows runtime that defaults to line-sequential text with LF delimiters and ASCII encoding. The production system uses z/OS data sets with fixed-block RECFM=FB, explicit LRECL, and EBCDIC code page 1047. SPECIAL-NAMES DECIMAL-POINT IS COMMA is present in the source but the local compiler dialect may ignore or interpret it differently.
Whether the logical FD description maps to identical physical record layout, character encoding, and decimal-point convention across both runtimes without additional compile-time or JCL directives.
What combination of CODE-SET, RECORD DELIMITER, compiler options, and JCL DCB parameters guarantees byte-for-byte equivalence? Which file-status values and runtime diagnostics should be captured to distinguish encoding mismatch from record-length mismatch? Does the production compiler require explicit TRUNC(BIN) or NUMCHECK to surface the same numeric-edited behavior seen locally?
35775 reputation · 31 Oct 2021, 09:33 UTC
No universal combination of CODE-SET, RECORD DELIMITER, compiler options, and JCL DCB guarantees byte-for-byte equivalence between an ASCII/LF local runtime and z/OS RECFM=FB EBCDIC CP1047. FILE-STATUS 00 means the I/O call completed; it does not prove the bytes were translated or that the record layout matches. The garbled alphanumeric fields are most likely local ASCII bytes interpreted as EBCDIC CP1047 on z/OS, while transposed decimal separators come from SPECIAL-NAMES DECIMAL-POINT IS COMMA being honored differently by the two compiler dialects.
Likely explanation: the file contains bytes encoded for the local ASCII runtime. The z/OS runtime reads those same bytes as EBCDIC CP1047 fixed-block records with no record delimiter, so USAGE DISPLAY alphanumeric fields contain unexpected byte values. FILE-STATUS 00 can coexist with this mismatch because USAGE DISPLAY carries no intrinsic encoding.
Confirmed facts:
RECFM=FB with explicit LRECL has no record delimiter; local line-sequential ASCII with LF is a different physical format.LRECL must equal the FD record length, and BLKSIZE should be a multiple of LRECL, to avoid truncation or padding.DECIMAL-POINT IS COMMA changes edited-numeric separator behavior, but compiler dialects differ on whether and how it is honored.TRUNC(BIN) mainly affects binary COMPUTATIONAL items; NUMCHECK validates numeric contents. Neither forces USAGE DISPLAY numeric-edited fields to a particular separator or code page.DCB to RECFM=FB,LRECL=fd-record-length,BLKSIZE=multiple-of-lrecl. Remove LINE SEQUENTIAL or LF delimiter handling unless both runtimes use it.CODE-SET only after confirming the target compiler supports it and that its syntax matches the intended EBCDIC code page.FILE-STATUS after every OPEN, READ, and WRITE, and write a hex dump of one known record on each system.DECIMAL-POINT convention.TRUNC(BIN) or NUMCHECK to make DISPLAY fields byte-identical; verify decimal-point behavior directly in the edited output.FILE-STATUS | Meaning in this context |
|---|---|
| 00 | I/O call completed; does not validate encoding or record layout |
| non-zero, implementation-specific | Length, access, or open error; consult the compiler file-status table |
Provide the exact COBOL compiler product and version used on z/OS. CODE-SET, RECORD DELIMITER, TRUNC, and NUMCHECK syntax and effects are dialect-specific, and an unsupported option can cause a compile failure or silent default instead of the intended conversion.
This answer assumes the production file is genuinely EBCDIC CP1047 as described and that the local file is ASCII. The exact CODE-SET clause and compiler option names cannot be selected without the target compiler identity, so treat all option syntax as pending verification.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 31 Oct 2021, 07:18 UTC
Clarify that the FD must define LRECL exactly equal to the JCL RECFM FB record length, and that any mismatch causes byte‑level corruption. File‑status 00 only confirms successful I/O, not that the bytes are correctly interpreted as ASCII or EBCDIC. Verify encoding by dumping the file in hex on both platforms and compare the numeric‑edited fields; the DECIMAL‑POINT IS COMMA clause may be honored differently by each compiler dialect. Recompile with explicit CODE‑SET EBCDIC and ensure DCB DSORG=PO and BLKSIZE is a multiple of LRECL.